2019.08.26
컨퍼런스를 다니며 기억보단 기록을하고자 합니다.
안녕하세요 이번에는 Kotlin/Everywhere Seoul 2019에 다녀왔습니다.
2019.08.26(월) Kotlin/Everywhere Seoul 2019
우선 이번 행사는 전세계에서 펼쳐지는 Kotlin축제로 Kotlin을 주제로하는 글로벌캠페인 입니다.
Kotlin/Everywhere에서는 Kotlin In Action의 저자중 한명인 JetBrains의 Developer Advocate이자 [Kotlin in Action]의 공동저자인 Svetlana Isakova(스베트라나 이사코바)가 방한하여 [What' new in Kotlin] 이라는 주제로 발표를 해주셨습니다.!!!(사인도 받았어요.!!👍🏻 맨아래 첨부) 그리고 GDE로 활동 하고 계신 노현석님께서도 [Koltin 히치하이커의 준비서] 라는 주제로 발표해주셨습니다(👏🏻👏🏻)
그럼 어떤내용으로 발표가 진행되었는지 하나씩 알아 보겠습니다.
Agenda
● Koltin evolution
● "Exprimental" feature
1. Inline Classes
2. Contracts
3. Immutable Collections
4. Flows
5. Multiplatform Projects
Kotlin evolution
< Principles of Pragmatic Evolution >
Language design is cast in stone, but this stone is reasonably soft, and with some effort we can reshape it later.
- Kotlin Design Team -
이 글은 Svetlana Isakova의 발표자료에 있던 내용인데, 이 문구는 Kotlin 공식 홈페이지에 올라와있는 내용이였습니다. 자세한 내용은 Kotlin evolution을 통해 확인해 보세요
코틀린은 프로그래머를 위한 실용적인 도구로 설계되었습니다. 언어 발전과 관련하여 실용적인 특성은 다음과 같은 원칙을 가집니다.
1. 언어를 현대적으로 유지 (KEEPing the language modern)
● KEEP = Kotlin Evolution and Enhancement Process
시간이 지남에 따라 시스템에는 레거시가 축적되는 것은 당연한 일입니다. 한때 최첨단이였던 기술이 오늘날에는 구식이 될 수 있습니다. 코틀린은 사용자의 요구와 관련성이 있고 기대와 최신 상태로 유지하기위해 언어를 발전시킵니다. 여기에는 새로운 기능 뿐만아니라 프로덕션 용도로 권장되지 않고 레거시가 된 오래된 기능을 제거하는것도 포함합니다.
2. 편안한 업데이트 (Comfortable Updates)
호환되지 않은 변경을 적절한 관리없이 수행할 경우 한 버전에서 다른 버전으로 마이그레이션 하는것은 매우 고통스럽습니다. 코틀린은 이러한 변경사항을 미리 발표하고 더이상 사용되지 않는것으로 표시하며, 변경이 발생하기전에 자동마이그레이션 도구를 제공합니다.
3. 피드백 루프 (Feedback Loop)
코틀린의 발전에는 피드백이 매우 중요하다고 합니다.
이제는 Features로 넘어가봅시다. 이부분은 초보인 저에게는 어려운 내용이였습니다. 한국어로 말해도 잘 이해하기 힘든부분을 영어로..ㅠ
그래도 열심히 들어보았습니다. 녹음도했구요...(55분...) 그래도 Svetlana Isakova가 엄청 천천히 말해줘서 느낌적인 느낌(?)은 얻을 수 있었습니다.ㅋ
Experimental features (실험적 기능들)
1. Inline Classes
Inline Class의 발표 내용을 요약하자면
● 추가 적인 오버헤드없이 래퍼 클래스를 이용한 값을 사용 할 수 있습니다.
● 현재 Inline Classes는 Kotlin 1.3이후 버전에서 사용할 수 있는 실험적 기능입니다.
그럼 조금더 알아보겠습니다.
발표 내용에서는 Duration API를 예제로 하였습니다.
/* Refining API : trying primitive args */
fun greetAfterTimeout(millis : Long)
greetAfterTimeOut(2) // 값의 의미가 seconds 인지 millseconds인지 불명확합니다.
/* Refining API : trying overloads */
fun greetAfterTimeoutMillis(millis : Long)
fun greetAfterTimeoutSeconds(seconds : Long)
greetAfterTimeoutSeconds(2) // 사용할 함수들이 장황해 집니다.
/* Refining API : trying class */
class Duration(val value : Long)
fun greeAfterTimeout(duration : Duration)
greetAfterTimeout(duration(2)) // 추가적인 객체 할당으로 오버헤드발생
/* Inline class to the rescue */
inline class Duration(val value : Long)
fun greetAfterTimeout(duration : Duration)
fun greetAfterTimeout_(duration : Long) // 추가적인 객체할당이 없습니다.
/* Creating Duration */
val Int.seconds
get() = toDuration(DurationUnit.SECONDS)
fun greetAfterTimeout(duration : Duration)
greetAfterTimeout(2.seconds) // 코드의 명시적 단위
이렇게 inline class를 사용함으로써 API를 개선하고 추가 할당을 방지하는 데 도움이 될 수 있다고 합니다.
Inline Class는 다음과 같은 특징을 가집니다.
* Inline Class는 init block을 가질 수 없습니다.
* lnline Class는 단하나의 val 프로퍼티만 가질 수 있습니다.
* Inline Class는 Backing Field를 가질 수 없습니다.
* Inline Class는 interface의 상속을 허용합니다.
아직 실험적 기능이니 차후에 좀더 알아보도록 하겠습니다.
참고
● https://kotlinlang.org/docs/reference/inline-classes.html
● https://github.com/kotlin-korea/Study-Log/issues/70
● https://medium.com/harrythegreat/kotlin-inline-noinline
● https://kotlinexpertise.com/kotlin-inline-classes/
● https://typealias.com/guides/introduction-to-inline-classes/
● https://github.com/Kotlin/KEEP/blob/master/proposals/inline-classes.md
2. Contracts
contracts에서 다뤄진 내용은 standard library 변경된 점을 설명해주었습니다.
Kotlin 1.3부터 기존에 있던 run, let코드에 contrat가 추가되었습니다.
public inline fun <R> run(block: () -> R): R = block()
↓
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
왜 추가되었을까?
기존 코드에서는 아래 사진과 같이 컴파일 에러가 나게됩니다.
직역하자면 "재할당 가능성으로 인한 캡처된 값의 초기화는 금지된다."
?? 무슨말인지 모르겠습니다..(에러메시지를 보고도 이해가되지 않습니다...)🤔
검색해본 결과 위의 에러는 val로 선언한 변수가 InvokeLambda블록 내의 코드가 실행되지 않거나 딱 한번만 실행될 수 있을지 보장(AT_MOST_ONCE)할 수 없기때문에 발생하는 capture values 오류와 invokeLambda블록 내의 코드가 한번이상 호출될 수있을지 보장(AT_LEAST_ONCE)할수 없기때문에 발생하는 initialize 오류 입니다.
이러한 오류는 컴파일러에게 정확히 한번만 실행하도록 보장(AT_MOST_ONCE)함과 코드가 한번이상 호출되는지 보장(AT_LEAST_ONCE)을 둘다 만족하는 정확히한번만 실행(ㄷEXACTLY_ONCE)를 contract를 통해 알려주어 오류를 해결할 수있습니다.
inline fun contractTest() : Int {
val intValue : Int
runTest {
// captured values init is forbidden 에러
intValue = 23
}
//variable must be initilized 에러
return intValue
}
inline fun <R>runTest(block: () -> R) = block()
위의 코드를 아래코드로 변경하여 오류를 해결 할 수있습니다.
@ExperimentalContracts
inline fun contractTest() : Int {
val intValue : Int
runTest {
// 에러발생 x
intValue = 23
}
// 에러발생 x
return intValue
}
@ExperimentalContracts
inline fun <R>runTest(block: () -> R) {
contract{
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
}
contract 관련한 내용은 해당 포스트에서 좀더 자세하게 보실수 있습니다.
참고
● https://medium.com/@lazysoul/kotlin에-추가된-contract-d6f14a055647
● https://medium.com/harrythegreat/kotlin-contracts-문법-쉽게-배워보기-9ffdc399aa75
● https://kotlinlang.org/docs/reference/whatsnew13.html
● https://pspdfkit.com/blog/2018/kotlin-contracts/
● https://ncorti.com/blog/discovering-kotlin-contracts
3. Immutable Collections
ImmutableList와 PersistentList를 사용하기 위해서는 아래의 Dependecy를 추가해주어야합니다.
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.2'
List는 Read-Only이며 Read-Only는 Immutable이 아니라고 설명하고있습니다.
(?) 이게 무슨 소리인가 싶었습니다. 저는 Read-Only가 Immutable인줄 알았습니다... 그래서 또 폭풍검색...
Immutable은 객체가 생성된 이후 그 상태를 변경할 수 없는 디자인 패턴을 의미합니다.
마이크로소프트의 C#에서 read-only의 의미를 가져왔습니다.
- 값 형식에는 해당 데이터가 직접 포함되므로, readonly 값 형식인 필드는 변경할 수 없습니다.
- 참조 형식에는 해당 데이터에 대한 참조가 포함되므로, readonly 참조 형식인 필드는 항상 같은 개체를 참조해야 합니다. 해당 개체는 변경할 수 있습니다. readonly 한정자는 필드가 참조 형식의 다른 인스턴스로 바뀌지 않도록 합니다. 그러나 한정자는 필드의 인스턴스 데이터가 읽기 전용 필드를 통해 수정되는 것을 방지하지는 않습니다.
그렇습니다. read-only는 항상 같은 개체를 참조해야되지만 참조개체는 변경될 수 있고, 변경된 개체를 참조하는 read-only의 참조값이 변경되었기때문에 Immutable하다라고 볼 수 없습니다.
그래서 나온 Immutable Collection과 Persistent Collection에 대해 좀더 알아 보겠습니다.
잘못 알고 있던 내용을 알게되어 기쁩니다!!
참고
● https://github.com/Kotlin/kotlinx.collections.immutable
● https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/readonly
4. Flows
Flow의 내용을 요약하자면 아래와 같습니다.
1. Suspend-based reactive stream
- Flow는 React Stream에서 Coruntine Libraray로 가져온것입니다.
2. Integration with RxJava
- 함수를 확장하여 할 수 있습니다.
- flow.asPublisher() / publisher.asFlow()
3. BackPressure
- Backpressure happens automatically thanks to suspension mechanism
Summary
-Flow는 현재 아주 실험적인 상태라고 합니다. 또한 곧 Stable이 될 것이라고 합니다.
참고
● https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/
● https://medium.com/@elizarov/simple-design-of-kotlin-flow-4725e7398c4c
5. Multiplatform Projects
kotlin에서는 모든 플랫폼에서 작업할 수 있는 것을 명백한 목표로 하고 있습니다. 즉, 위 사진에서 보이는바와 같이 공통코드로 Server / Android / IOS / Browser 플랫폼을 액세스 하겠다는 의미 입니다.
또한 여기서 의미하는 공통코드는
• Sharing business logic (비즈니스 로직의 공유)
• Keeping UI platform-dependent (UI 플랫폼 의존성을 유지)
• The shared part might vary (공유된 부분은 다를수 있음)
라고 합니다. 이제 실제로 예제 샘플을 한번 보도록 하겠습니다.
expect fun measureTime(action: () - Unit): Duration
measureTime {
//operation
}
// Kotlin/JVM
actual fun measureTime(action: () - Unit): Duration {
// implementation using System.nanoTime()
}
// Koltin/Native
actual fun measureTime(action: () - Unit): Duration {
// implementation using std::chrono::high_resolution_clock
}
// Kotlin/JS
actual fun measureTime(action: () - Unit): Duration {
// implementation using window.performance.now()
}
• you define expect declarations in the common code and use them
- expect 키워드를 통해 공통코드를 정의하고 사용할 수 있다.
• you provide different actual implementations for different platforms
- actual 키워드를 통해 각각 다른 플랫폼에서 실제구현을 제공한다.
참고
● https://kotlinlang.org/docs/reference/multiplatform.html
마치며
이번 포스트는 단지 컨퍼런스에서 소개된 내용[What's new in Kotlin]을 전달드리며, 소개된 내용의 자세한 부분들은 추후 열심히! 공부해서 다시 포스팅 해보겠습니다. 감사합니다. 마지막으로 사인!! 👏🏻
Have a nice Kotlin !!
감사합니다.
❤️
Love YourSelf
'컨퍼런스' 카테고리의 다른 글
[컨퍼런스] DevFest Pangyo 2019 : Fun Thing is Good! 후기 (0) | 2019.11.16 |
---|---|
[Hackathon] DODO 14회 참석 후기 (0) | 2019.09.28 |
[컨퍼런스] Android Studio Build Talk 후기 (0) | 2019.09.23 |
[컨퍼런스] 제3회 99콘<이력서> 후기 (1) | 2019.09.21 |
[컨퍼런스] 안드로이드 탐구영역 (0) | 2019.09.01 |