SlideShare una empresa de Scribd logo
1 de 88
Descargar para leer sin conexión
Kotlin 2.0 을 통해
알아보는 Kotlin의 미래
Leonardo YongUk Kim
2023.05
2
Contents
01
02
03
04
05
Kotlin 2.0 및 추가적인 언어의 진화
Kotlin Multiplatform
Compose for iOS
Compose for Desktop
Compose for Web
1. Kotlin 2.0 및 추가적인 언어 진화
K2 세계에서 두 번째로 높은 산. Kotlin 2.0에 도입되는 프론트엔드
5
K2 컴파일러의 압도적인 프론트엔드 향상
https://blog.jetbrains.com/ko/kotlin/2023/04/kotlinconf-2023-opening-keynote/
6
프론트엔드와 백엔드가 무엇인가요?
프론트
엔드
파서와 시멘틱 애널라이저로 구성.
소스코드를 읽어 구문 트리를 만들고 의미 정보를
추가함.
백엔드
중간 코드 생성 & 최적화기와 머신 코드 생성 최적
화로 나누어짐.
최적화를 하고 기계어 코드나 타겟 코드를 생성.
코틀린의 경우에는 자바 Bytecode나 LLVM의
Bitcode가 타겟.
코틀린
코틀린의 경우에 (1.3까지) 중간 코드 생성 & 최적
화기가 없었음.
효율보다는 코틀린 언어의 발전이 더 중요했음.
(기술부채)
https://twitter.com/kotlin
7
백엔드에 IR의 도입
IR 백엔드에서 공유하는 중간 수준의 언어
IR
generator
& optimizer
IR을 만들고 최적화 하는 파트.
코틀린 네이티브를 만들며 새롭게 추가. 이
후 JVM(1.5)과 JS(1.6)을 IR을 쓰도록 재
작성.
공통적인 최적화를 할 수 있다. (그전까지
는 백엔드마다 별도로 작성.)
의도하지는 않았지만 새 백엔드의 성능이
향상!
https://twitter.com/kotlin
남은 것은 프론트엔드
레거시 PSI (Program Structure Interface)
PSI
Program Structure Interface
코틀린 코드를 파싱한 결과 트리. IntelliJ에서 먼저 쓰던 구조를 코틀린 컴파일러도 차용.
소스 코드와 거의 대응되는 단순한 형태.
PSIViewer로 PSI를 확인 가능
의미를 담는 BindingContext
Kotlin Compiler In past, 1.4 and beyond
의미를 담는 BindingContext
Kotlin Compiler In past, 1.4 and beyond
의미를 담는 BindingContext
Kotlin Compiler In past, 1.4 and beyond
PSI + BindingContext가 문제가 있나요?
최적화
프론트엔드 수준에서 PSI에서 최적화를 하는 것이 쉽지 않음.
문맥이 별도의 BIndingContext에 있는 것도 최적화에 좋지 못함.
캐쉬 미스 BindingContext가 거대한 Map이어서 캐쉬 효율에 좋지 못함.
Frontend Intermediate Representation
백엔드에게 전달할 새로운 중간 언어
https://twitter.com/kotlin
Kotlin FIR Viewer
FIR을 볼 수 있는 뷰어 https://github.com/google/Kotlin-FirViewer
Kotlin Compiler In past, 1.4 and beyond
프론트엔드
왜 FIR이 두개가 있나요?
파서 Raw FIR 빌더 Analyze
체커
파스트리 FIR FIR
진단
Lowering
단순화(simplify)라고 설명. 디슈거링(Desugraing)이라고도 표현.
비구조화 (Desctructure)를 연속된 대입으로 변경.
for 등을 while으로 변경. 연산자(+, +=, in, …)등을 명시적인 호출로 변형.
기타 프론트엔드 수준에서의 최적화도 수행.
18
FIR 기반의 프론트엔트의 장점
컴파일러 성능 FIR 기반으로 만든 프론트엔드는 PSI + BindingContext 기반의 프론트엔드 보다 훨신 빠름.
IDE
IDE도 프론트엔드를 공유. 인텔리제이에서 의미를 파악하고 코드 하이라이팅, 분석하는 속도가 빨라짐.
Kotlin IDE 플러그인 재작성중.
19
가장 많이 요청받은 기능
Static Extensions 인스턴스가 아니더라도 확장 함수를 만들 수 있음.
Collection Literals listOf, mapOf, setOf 가 아닌 리터럴로 컬렉션.
Name-based Destructuring 비구조화(구조분해)를 위치 기반이 아니라 이름 기반으로.
Explicit Fields 같은 컨셉의 private, public 프로퍼티를 만들지 않아도 됨.
Context Receivers 멤버 확장 함수 이외에 Context를 지정할 방법의 추가.
20
정적 확장 (Static Extensions)
https://youtrack.jetbrains.com/issue/KT-11968
File.open("data.txt")
21
정적 확장 (Static Extensions)
https://youtrack.jetbrains.com/issue/KT-11968
File.open("data.txt")
fun File.Companion.open(name: String)
22
정적 확장 (Static Extensions)
https://youtrack.jetbrains.com/issue/KT-11968
File.open("data.txt")
fun File.Companion.open(name: String)
23
정적 확장 (Static Extensions)
https://youtrack.jetbrains.com/issue/KT-11968
File.open("data.txt")
fun File.Static.open(name: String)
24
컬렉션 리터럴 (Collection Literals)
https://youtrack.jetbrains.com/issue/KT-43871
cmdArgs = listOf("-language-version", "2.0")
25
컬렉션 리터럴 (Collection Literals)
https://youtrack.jetbrains.com/issue/KT-43871
cmdArgs = [“-language-version", “2.0"]
26
컬렉션 리터럴 (Collection Literals)
https://youtrack.jetbrains.com/issue/KT-43871
cmdArgs = [“-language-version", “2.0”]
val skip = persistentSetOf<Int>(0, 1)
27
컬렉션 리터럴 (Collection Literals)
https://youtrack.jetbrains.com/issue/KT-43871
cmdArgs = [“-language-version", “2.0”]
val skip: PersistentSet<Int> = [0, 1]
28
컬렉션 리터럴 (Collection Literals)
https://youtrack.jetbrains.com/issue/KT-43871
cmdArgs = [“-language-version", “2.0”]
val skip = PersistentSet [0, 1]
29
이름 기반 비구조화 (Name-Based Restructuring)
https://youtrack.jetbrains.com/issue/KT-19627
data class Person(
val
fi
rstName: String,
val lastName: String
)
30
이름 기반 비구조화 (Name-Based Restructuring)
https://youtrack.jetbrains.com/issue/KT-19627
data class Person(
val
fi
rstName: String,
val lastName: String
)
val (
fi
rstName, lastName) = person
31
이름 기반 비구조화 (Name-Based Restructuring)
https://youtrack.jetbrains.com/issue/KT-19627
data class Person(
val
fi
rstName: String,
val lastName: String
)
val (lastName,
fi
rstName) = person
32
컨택스트 수신자 (Context Receivers)
https://youtrack.jetbrains.com/issue/KT-10468
fun process(
context: ServiceContext,
request: ServiceRequest
) {
val data = request.loadData(context)
}
33
컨택스트 수신자 (Context Receivers)
https://youtrack.jetbrains.com/issue/KT-10468
fun process(
context: ServiceContext,
request: ServiceRequest
) {
val data = request.loadData(context)
}
context(ServiceContext)
fun processRequest(request: ServiceRequest)
34
컨택스트 수신자 (Context Receivers)
https://youtrack.jetbrains.com/issue/KT-10468
context(ServiceContext)
fun processRequest(request: ServiceRequest) {
val data = request.loadData()
//
}
35
컨택스트 수신자 (Context Receivers)
https://youtrack.jetbrains.com/issue/KT-10468
context(ServiceContext)
fun processRequest(request: ServiceRequest) {
val data = request.loadData()
//
}
context(ServiceContext)
fun ServiceRequest.loadData(): Data
36
명시적 필드 (Explicit Fields)
https://youtrack.jetbrains.com/issue/KT-14663
private val _applicationState =
MutableStateFlow(State())
val applicationState: StateFlow<State>
get() = _applicationState
37
명시적 필드 (Explicit Fields)
https://youtrack.jetbrains.com/issue/KT-14663
private val _applicationState =
MutableStateFlow(State())
val applicationState: StateFlow<State>
get() = _applicationState
val applicationState: StateFlow<State>
fi
eld = MutableStateFlow(State())
38
데이터프레임
https://github.com/kotlin/dataframe
val df = DataFrame.readCSV("KotlinSO.csv")
39
데이터프레임
https://github.com/kotlin/dataframe
val df = DataFrame.readCSV("KotlinSO.csv")
val kmp = df.
fi
lter {
tags?.contains("multiplatform")
?: false
}
40
K2 프론트엔드에서는 플러그인을 적용하기 쉬워서 해결
val df = DataFrame.readCSV("KotlinSO.csv")
val kmp = df.
fi
lter {
tags?.contains("multiplatform")
?: false
}
kmp.add("years") { creationData.year }
.groupBy { year }
.count()
41
데이터프레임
2. Kotlin Multiplatform
43
매년 멀티플랫폼 라이브러리는 증가.
44
코틀린 멀티플랫폼은 아직 베타 단계
45
Kotlin Multiplatform 라이브러리
46
Kotlin Multiplatform Mobile을 위해 필요한 것
Android
Studio
멀티플랫폼 애플리케이션을 만들고 시물레이터나 하드웨어를 실행.
47
Kotlin Multiplatform Mobile을 위해 필요한 것
Xcode
Xcode는 백그라운드에서 수행 됨.
Kotlin/Native가 의존하는 버전을 설치해야 함.
48
Kotlin Multiplatform Mobile을 위해 필요한 것
Kotlin
Multiplatform
Mobile
안드로이드 스튜디오에서 Kotlin Multiplatform Mobile 플러그인 설치.
49
Kotlin Multiplatform Mobile을 위해 필요한 것
JDK Android Studio에 의해 설치.
Kotlin Plugin Android Studio에 설치. 업데이트를 해서 버전을 최신화 해야.
50
Kotlin Multiplatform Mobile을 위해 필요한 것
KDoctor KMM을 위해 필요한 환경이 있는지 점검하는 앱.
51
52
Kotlin Multiplatform Mobile을 위해 필요한 것
CocoaPods KMM은 SPM(SwiftPackageManager)를 지원하지 않음. (대체 왜!)
53
Kotlin Multiplatform App으로 새 프로젝트를 만듬.
54
패키지 네임은 안드로이드/자바 앱처럼 도메인의 역순으로 지정함.
55
앱 네임
기본으로 androidApp, iosApp, shared로 앱 네임이 정해짐.
iOS framework distribution은 Regular로 Cocoapods -_-을 선택할 수 있음.
56
androidApp 안드로이드 관련 코드는 androidApp 아래 위치함
57
안드로이드는
Compose로 생성 됨
58
iosApp iOS 관련 코드는 iOSApp에 위치함.
59
iOS는 SwiftUI로
Compose 아닙니다.
60
61
버전 처리는 어떻게 했을까요?
expect와 actual
shared/src/
commonMain
iOS와 Android에서 모두 사용할 인터페이스를 expect 키워드로 만듬.
62
버전 처리는 어떻게 했을까요?
expect와 actual
shared/src/
androidMain
Android의 구현을 actual 키워드를 붙여 구현
63
버전 처리는 어떻게 했을까요?
expect와 actual
shared/src/
iOSMain
iOS의 구현을 actual 키워드를 붙여 구현
64
KMM for iOS에서 만나게 되는 상황들
ObjC
현재 Kotlin은 ObjC만 지원해서 제너릭 클래스만 지원하고 인터페이스를 지원하지 못함. Abstract
class를 대신 사용해야 함.
@HinddenFromObjC, @ObjcName 키워드를 적극적으로 활용하자.
@ObjcName(swiftName=“_”) _는 특수한 키워드.
plane.fuel(volume: .Gallos(gallos: 12.5)) 대신 plane.fuel(.Gallons(12.5))
장기적으로는 코트린이 Swift를 바로 타게팅할 것임. Swift를 ObjeC를 제외하고 바인드할 수 없었기에 발
생한 문제.
SourceKitten와 같은 도구들로 중간 코드를 생성하자.
라인 데메에카이 겪은 어려움
Suspend
suspend는 콜백(completion handler)이 되고 콜백은 Swift에서 async로 호출 가능하지만 취소가 불
가능함. Flow도 잘 지원되지 않음.
KMP-NativeCoroutines 라이브러리를 활용해야 함.
https://github.com/rickclephas/KMP-NativeCoroutines
코틀린 예외가 스위프트 핸들러 전달 되지 않을 수 있어 @Throws 키워드로 Error를 지정해야 함.
65
KMM for iOS에서 만나게 되는 상황들
CocoaPods
아직 공식적으로 SPM(Swift Package Manager)를 지원하지 않음. Gradle API 수준에서 정리된 이후
에 지원한다고 함. (언제?)
CocoaPods는 의존성을 소스로 가져와 같이 빌드에 사용하기에 매우 비효율적.
TouchLab의 라이브러리 KMMBridge를 사용합시다.
https://github.com/touchlab/KMMBridge
SPM을 대응하기 위해서는 Git 리포지토리와 스태틱 파일 저장소가 필요하다. (AWS?)
Frozen
Global Object는 기본으로 frozen. 접근할 수 있지만 변경할 수 없음.
@ThreadLocal을 붙이면 freeze 호출 안함. Atomic한 자료구조의 사용이 필요할 수 있다.
freeze() 확장 함수를 이용해 데이터를 얼릴 수 있고 풀 수는 없음.
Global 프로퍼티는 메인스레드에서만 볼 수 있음.
66
KMM for iOS에서 만나게 되는 상황들
Memory
Management
스택 트레이스 디버깅 어렵고, 메모리 매니지먼트가 아직 안정적이지는 않음.
https://youtrack.jetbrains.com/issue/KT-55512
참고
Kotlin Multiplatform Mobile을 활용한 데마에칸 드라이버앱 개발 이야기
Kotlin/Multiplatform for iOS developers : state & future by Salomon Brys
3. Compose for iOS
68
Compose Multiplatform mobile application
템플릿을 이용해서 시작해야
템플릿 https://github.com/JetBrains/compose-multiplatform-ios-android-template
69
Compose for iOS를 위해 필요한 것
Android
Studio
Android 앱과 iOS 앱를 실행할 수 있는 개발 환경.
Xcode
Xcode는 백그라운드에서 수행 됨.
Kotlin/Native가 의존하는 버전을 설치해야 함.
Kotlin
Multiplatform
Mobile
안드로이드 스튜디오에서 Kotlin Multiplatform Mobile 플러그인 설치.
CocoaPods Compose for iOS도 SPM(SwiftPackageManager)를 지원하지 않음.
70
Compose for iOS를 위해 필요한 것
71
shared/src/
commonMain
72
androidApp/
src/
commonMain
73
iosApp/
iosApp
74
iosApp/
iosApp
75
sharedApp/
src/iosMain
76
처음 변경해보는 Compose for iOS
TextField 추가 TextField를 추가하는 데모를 합시다.
4. Compose for Desktop
78
Compose for Desktop의 특징
Cross-
Platform
멀티플랫폼이 아닌 크로스플랫폼으로 분류.
JVM이 타겟이고 JVM 덕에 여러 플랫폼에서 도는 것을 크로스플랫폼으로 설명.
SKIKO
SKIA의 코틀린 바인딩 SKIKO에 의해 렌더링. https://github.com/JetBrains/skiko
SKIA의 폰트 렌더링이 운영체제 마다 달라 스크린 샷 테스트를 하지 말자.
Compose
Multiplatform
IDE support
인텔리제이 아이디어나 안드로이드 스튜디오에 설치.
https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support
IntelliJ IDEA 인텔리제이 아이디어 2020.3 이상에서 사용가능.
79
Compose for Desktop의 특징
참고영상 You can do desktop too! By Victor Kropp
https://www.youtube.com/watch?v=Mgf_9kxM1BA
JDK 15 JDK11으로 프로젝트 생성 가능. 네이티브 배포 패키징을 위해서는 15 이상.
80
Compose Multiplatform desktop application
New Project로 시작하기
81
82
5. Compose for Web
84
Compose for Web의 특징
WebAssembly
JavaScript를 쓰지 않고 WebAssembly로 실행.
Kotlin/WASM이 타겟.
Compose
HTML
HTML을 생성하는 Kotlin/JS의 라이브러리도 있음.
Compose for Web과 무관.
Compose
Multiplatform
IDE support
인텔리제이 아이디어나 안드로이드 스튜디오에 설치.
https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support
IntelliJ IDEA 인텔리제이 아이디어 2020.3 이상에서 사용가능.
85
WASM 예제 https://github.com/Kotlin/kotlin-wasm-examples
86
87
끝

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Android internals 07 - Android graphics (rev_1.1)
Android internals 07 - Android graphics (rev_1.1)Android internals 07 - Android graphics (rev_1.1)
Android internals 07 - Android graphics (rev_1.1)
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricks
 
.NET and C# introduction
.NET and C# introduction.NET and C# introduction
.NET and C# introduction
 
Implementation of k means algorithm on Hadoop
Implementation of k means algorithm on HadoopImplementation of k means algorithm on Hadoop
Implementation of k means algorithm on Hadoop
 
(DEV307) Introduction to Version 3 of the AWS SDK for Python (Boto) | AWS re:...
(DEV307) Introduction to Version 3 of the AWS SDK for Python (Boto) | AWS re:...(DEV307) Introduction to Version 3 of the AWS SDK for Python (Boto) | AWS re:...
(DEV307) Introduction to Version 3 of the AWS SDK for Python (Boto) | AWS re:...
 
The TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux KernelThe TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux Kernel
 
Moving NEON to 64 bits
Moving NEON to 64 bitsMoving NEON to 64 bits
Moving NEON to 64 bits
 
Flutter introduction
Flutter introductionFlutter introduction
Flutter introduction
 
Favor composition over inheritance
Favor composition over inheritanceFavor composition over inheritance
Favor composition over inheritance
 
Android 10
Android 10Android 10
Android 10
 
Google App Engine
Google App EngineGoogle App Engine
Google App Engine
 
ROS2 on VxWorks - one project on Wind River Labs
ROS2 on VxWorks - one project on Wind River LabsROS2 on VxWorks - one project on Wind River Labs
ROS2 on VxWorks - one project on Wind River Labs
 
Android share preferences
Android share preferencesAndroid share preferences
Android share preferences
 
Introduction To C#
Introduction To C#Introduction To C#
Introduction To C#
 
Kotlin Multiplatform
Kotlin MultiplatformKotlin Multiplatform
Kotlin Multiplatform
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
CMake - Introduction and best practices
CMake - Introduction and best practicesCMake - Introduction and best practices
CMake - Introduction and best practices
 
Cómo domar SonataAdminBundle
Cómo domar SonataAdminBundleCómo domar SonataAdminBundle
Cómo domar SonataAdminBundle
 
Hibernate Basic Concepts - Presentation
Hibernate Basic Concepts - PresentationHibernate Basic Concepts - Presentation
Hibernate Basic Concepts - Presentation
 
ACPI Debugging from Linux Kernel
ACPI Debugging from Linux KernelACPI Debugging from Linux Kernel
ACPI Debugging from Linux Kernel
 

Similar a Kotlin 2.0을 통해 알아보는 코틀린의 미래

Mozilla 오픈 웹 모바일 플랫폼 (2012)
Mozilla 오픈 웹 모바일 플랫폼 (2012)Mozilla 오픈 웹 모바일 플랫폼 (2012)
Mozilla 오픈 웹 모바일 플랫폼 (2012)
Channy Yun
 

Similar a Kotlin 2.0을 통해 알아보는 코틀린의 미래 (20)

Compose Multiplatform 101
Compose Multiplatform 101Compose Multiplatform 101
Compose Multiplatform 101
 
ifcpp build guide
ifcpp build guideifcpp build guide
ifcpp build guide
 
코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우
 
[170403 2주차]C언어 A반
[170403 2주차]C언어 A반[170403 2주차]C언어 A반
[170403 2주차]C언어 A반
 
DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기
 
C++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & NanaC++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & Nana
 
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
 
Gradle Kotlin 컨벤션 플러그인으로 효율적으로 멀티 모듈 관리하기
Gradle Kotlin 컨벤션 플러그인으로 효율적으로 멀티 모듈 관리하기Gradle Kotlin 컨벤션 플러그인으로 효율적으로 멀티 모듈 관리하기
Gradle Kotlin 컨벤션 플러그인으로 효율적으로 멀티 모듈 관리하기
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
SOSCON 2017 - Backend.AI
SOSCON 2017 - Backend.AISOSCON 2017 - Backend.AI
SOSCON 2017 - Backend.AI
 
Win10 iot core_pi2
Win10 iot core_pi2Win10 iot core_pi2
Win10 iot core_pi2
 
OpenStack Horizon AWS Plugin For Hybrid Cloud
OpenStack Horizon AWS Plugin For Hybrid CloudOpenStack Horizon AWS Plugin For Hybrid Cloud
OpenStack Horizon AWS Plugin For Hybrid Cloud
 
swift를 이용한 카카오링크 만들기
swift를 이용한 카카오링크 만들기swift를 이용한 카카오링크 만들기
swift를 이용한 카카오링크 만들기
 
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
 
Unity Auto Build iOS
Unity Auto Build iOSUnity Auto Build iOS
Unity Auto Build iOS
 
Mozilla 오픈 웹 모바일 플랫폼 (2012)
Mozilla 오픈 웹 모바일 플랫폼 (2012)Mozilla 오픈 웹 모바일 플랫폼 (2012)
Mozilla 오픈 웹 모바일 플랫폼 (2012)
 
Portfolio
PortfolioPortfolio
Portfolio
 
Lablupconf session8 "Paving the road to AI-powered world"
Lablupconf session8 "Paving the road to AI-powered world"Lablupconf session8 "Paving the road to AI-powered world"
Lablupconf session8 "Paving the road to AI-powered world"
 
디자인에 이어 코딩까지 AI가 프로그램 개발을 척척?: GitHub Copilot, 어디까지 알아보셨나요
디자인에 이어 코딩까지 AI가 프로그램 개발을 척척?: GitHub Copilot, 어디까지 알아보셨나요디자인에 이어 코딩까지 AI가 프로그램 개발을 척척?: GitHub Copilot, 어디까지 알아보셨나요
디자인에 이어 코딩까지 AI가 프로그램 개발을 척척?: GitHub Copilot, 어디까지 알아보셨나요
 
델파이 소스코드의재발견
델파이 소스코드의재발견델파이 소스코드의재발견
델파이 소스코드의재발견
 

Más de Leonardo YongUk Kim

Más de Leonardo YongUk Kim (20)

안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계
 
Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?Realm은 어떻게 효율적인 데이터베이스를 만들었나?
Realm은 어떻게 효율적인 데이터베이스를 만들었나?
 
MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지
 
Anatomy of Realm
Anatomy of RealmAnatomy of Realm
Anatomy of Realm
 
PublishSubject
PublishSubjectPublishSubject
PublishSubject
 
Tensorflow 101
Tensorflow 101Tensorflow 101
Tensorflow 101
 
Realm과 RxJava
Realm과 RxJavaRealm과 RxJava
Realm과 RxJava
 
A brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinA brief introduction to Realm with Kotlin
A brief introduction to Realm with Kotlin
 
Realm Java
Realm JavaRealm Java
Realm Java
 
역시 Redux
역시 Redux역시 Redux
역시 Redux
 
3D Graphics 101
3D Graphics 1013D Graphics 101
3D Graphics 101
 
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
 
Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스
 
React Everywhere
React EverywhereReact Everywhere
React Everywhere
 
React Redux React Native
React Redux React NativeReact Redux React Native
React Redux React Native
 
Veni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle PluginVeni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle Plugin
 
A brief guide to android gradle
A brief guide to android gradleA brief guide to android gradle
A brief guide to android gradle
 
Modern android
Modern androidModern android
Modern android
 
Butter android views
Butter android viewsButter android views
Butter android views
 
Actionbar and fragment
Actionbar and fragmentActionbar and fragment
Actionbar and fragment
 

Kotlin 2.0을 통해 알아보는 코틀린의 미래

  • 1. Kotlin 2.0 을 통해 알아보는 Kotlin의 미래 Leonardo YongUk Kim 2023.05
  • 2. 2 Contents 01 02 03 04 05 Kotlin 2.0 및 추가적인 언어의 진화 Kotlin Multiplatform Compose for iOS Compose for Desktop Compose for Web
  • 3. 1. Kotlin 2.0 및 추가적인 언어 진화
  • 4. K2 세계에서 두 번째로 높은 산. Kotlin 2.0에 도입되는 프론트엔드
  • 5. 5 K2 컴파일러의 압도적인 프론트엔드 향상 https://blog.jetbrains.com/ko/kotlin/2023/04/kotlinconf-2023-opening-keynote/
  • 6. 6 프론트엔드와 백엔드가 무엇인가요? 프론트 엔드 파서와 시멘틱 애널라이저로 구성. 소스코드를 읽어 구문 트리를 만들고 의미 정보를 추가함. 백엔드 중간 코드 생성 & 최적화기와 머신 코드 생성 최적 화로 나누어짐. 최적화를 하고 기계어 코드나 타겟 코드를 생성. 코틀린의 경우에는 자바 Bytecode나 LLVM의 Bitcode가 타겟. 코틀린 코틀린의 경우에 (1.3까지) 중간 코드 생성 & 최적 화기가 없었음. 효율보다는 코틀린 언어의 발전이 더 중요했음. (기술부채) https://twitter.com/kotlin
  • 7. 7 백엔드에 IR의 도입 IR 백엔드에서 공유하는 중간 수준의 언어 IR generator & optimizer IR을 만들고 최적화 하는 파트. 코틀린 네이티브를 만들며 새롭게 추가. 이 후 JVM(1.5)과 JS(1.6)을 IR을 쓰도록 재 작성. 공통적인 최적화를 할 수 있다. (그전까지 는 백엔드마다 별도로 작성.) 의도하지는 않았지만 새 백엔드의 성능이 향상! https://twitter.com/kotlin
  • 8. 남은 것은 프론트엔드 레거시 PSI (Program Structure Interface) PSI Program Structure Interface 코틀린 코드를 파싱한 결과 트리. IntelliJ에서 먼저 쓰던 구조를 코틀린 컴파일러도 차용. 소스 코드와 거의 대응되는 단순한 형태.
  • 10. 의미를 담는 BindingContext Kotlin Compiler In past, 1.4 and beyond
  • 11. 의미를 담는 BindingContext Kotlin Compiler In past, 1.4 and beyond
  • 12. 의미를 담는 BindingContext Kotlin Compiler In past, 1.4 and beyond
  • 13. PSI + BindingContext가 문제가 있나요? 최적화 프론트엔드 수준에서 PSI에서 최적화를 하는 것이 쉽지 않음. 문맥이 별도의 BIndingContext에 있는 것도 최적화에 좋지 못함. 캐쉬 미스 BindingContext가 거대한 Map이어서 캐쉬 효율에 좋지 못함.
  • 14. Frontend Intermediate Representation 백엔드에게 전달할 새로운 중간 언어 https://twitter.com/kotlin
  • 15. Kotlin FIR Viewer FIR을 볼 수 있는 뷰어 https://github.com/google/Kotlin-FirViewer
  • 16. Kotlin Compiler In past, 1.4 and beyond
  • 17. 프론트엔드 왜 FIR이 두개가 있나요? 파서 Raw FIR 빌더 Analyze 체커 파스트리 FIR FIR 진단 Lowering 단순화(simplify)라고 설명. 디슈거링(Desugraing)이라고도 표현. 비구조화 (Desctructure)를 연속된 대입으로 변경. for 등을 while으로 변경. 연산자(+, +=, in, …)등을 명시적인 호출로 변형. 기타 프론트엔드 수준에서의 최적화도 수행.
  • 18. 18 FIR 기반의 프론트엔트의 장점 컴파일러 성능 FIR 기반으로 만든 프론트엔드는 PSI + BindingContext 기반의 프론트엔드 보다 훨신 빠름. IDE IDE도 프론트엔드를 공유. 인텔리제이에서 의미를 파악하고 코드 하이라이팅, 분석하는 속도가 빨라짐. Kotlin IDE 플러그인 재작성중.
  • 19. 19 가장 많이 요청받은 기능 Static Extensions 인스턴스가 아니더라도 확장 함수를 만들 수 있음. Collection Literals listOf, mapOf, setOf 가 아닌 리터럴로 컬렉션. Name-based Destructuring 비구조화(구조분해)를 위치 기반이 아니라 이름 기반으로. Explicit Fields 같은 컨셉의 private, public 프로퍼티를 만들지 않아도 됨. Context Receivers 멤버 확장 함수 이외에 Context를 지정할 방법의 추가.
  • 20. 20 정적 확장 (Static Extensions) https://youtrack.jetbrains.com/issue/KT-11968 File.open("data.txt")
  • 21. 21 정적 확장 (Static Extensions) https://youtrack.jetbrains.com/issue/KT-11968 File.open("data.txt") fun File.Companion.open(name: String)
  • 22. 22 정적 확장 (Static Extensions) https://youtrack.jetbrains.com/issue/KT-11968 File.open("data.txt") fun File.Companion.open(name: String)
  • 23. 23 정적 확장 (Static Extensions) https://youtrack.jetbrains.com/issue/KT-11968 File.open("data.txt") fun File.Static.open(name: String)
  • 24. 24 컬렉션 리터럴 (Collection Literals) https://youtrack.jetbrains.com/issue/KT-43871 cmdArgs = listOf("-language-version", "2.0")
  • 25. 25 컬렉션 리터럴 (Collection Literals) https://youtrack.jetbrains.com/issue/KT-43871 cmdArgs = [“-language-version", “2.0"]
  • 26. 26 컬렉션 리터럴 (Collection Literals) https://youtrack.jetbrains.com/issue/KT-43871 cmdArgs = [“-language-version", “2.0”] val skip = persistentSetOf<Int>(0, 1)
  • 27. 27 컬렉션 리터럴 (Collection Literals) https://youtrack.jetbrains.com/issue/KT-43871 cmdArgs = [“-language-version", “2.0”] val skip: PersistentSet<Int> = [0, 1]
  • 28. 28 컬렉션 리터럴 (Collection Literals) https://youtrack.jetbrains.com/issue/KT-43871 cmdArgs = [“-language-version", “2.0”] val skip = PersistentSet [0, 1]
  • 29. 29 이름 기반 비구조화 (Name-Based Restructuring) https://youtrack.jetbrains.com/issue/KT-19627 data class Person( val fi rstName: String, val lastName: String )
  • 30. 30 이름 기반 비구조화 (Name-Based Restructuring) https://youtrack.jetbrains.com/issue/KT-19627 data class Person( val fi rstName: String, val lastName: String ) val ( fi rstName, lastName) = person
  • 31. 31 이름 기반 비구조화 (Name-Based Restructuring) https://youtrack.jetbrains.com/issue/KT-19627 data class Person( val fi rstName: String, val lastName: String ) val (lastName, fi rstName) = person
  • 32. 32 컨택스트 수신자 (Context Receivers) https://youtrack.jetbrains.com/issue/KT-10468 fun process( context: ServiceContext, request: ServiceRequest ) { val data = request.loadData(context) }
  • 33. 33 컨택스트 수신자 (Context Receivers) https://youtrack.jetbrains.com/issue/KT-10468 fun process( context: ServiceContext, request: ServiceRequest ) { val data = request.loadData(context) } context(ServiceContext) fun processRequest(request: ServiceRequest)
  • 34. 34 컨택스트 수신자 (Context Receivers) https://youtrack.jetbrains.com/issue/KT-10468 context(ServiceContext) fun processRequest(request: ServiceRequest) { val data = request.loadData() // }
  • 35. 35 컨택스트 수신자 (Context Receivers) https://youtrack.jetbrains.com/issue/KT-10468 context(ServiceContext) fun processRequest(request: ServiceRequest) { val data = request.loadData() // } context(ServiceContext) fun ServiceRequest.loadData(): Data
  • 36. 36 명시적 필드 (Explicit Fields) https://youtrack.jetbrains.com/issue/KT-14663 private val _applicationState = MutableStateFlow(State()) val applicationState: StateFlow<State> get() = _applicationState
  • 37. 37 명시적 필드 (Explicit Fields) https://youtrack.jetbrains.com/issue/KT-14663 private val _applicationState = MutableStateFlow(State()) val applicationState: StateFlow<State> get() = _applicationState val applicationState: StateFlow<State> fi eld = MutableStateFlow(State())
  • 39. 39 데이터프레임 https://github.com/kotlin/dataframe val df = DataFrame.readCSV("KotlinSO.csv") val kmp = df. fi lter { tags?.contains("multiplatform") ?: false }
  • 40. 40 K2 프론트엔드에서는 플러그인을 적용하기 쉬워서 해결 val df = DataFrame.readCSV("KotlinSO.csv") val kmp = df. fi lter { tags?.contains("multiplatform") ?: false } kmp.add("years") { creationData.year } .groupBy { year } .count()
  • 46. 46 Kotlin Multiplatform Mobile을 위해 필요한 것 Android Studio 멀티플랫폼 애플리케이션을 만들고 시물레이터나 하드웨어를 실행.
  • 47. 47 Kotlin Multiplatform Mobile을 위해 필요한 것 Xcode Xcode는 백그라운드에서 수행 됨. Kotlin/Native가 의존하는 버전을 설치해야 함.
  • 48. 48 Kotlin Multiplatform Mobile을 위해 필요한 것 Kotlin Multiplatform Mobile 안드로이드 스튜디오에서 Kotlin Multiplatform Mobile 플러그인 설치.
  • 49. 49 Kotlin Multiplatform Mobile을 위해 필요한 것 JDK Android Studio에 의해 설치. Kotlin Plugin Android Studio에 설치. 업데이트를 해서 버전을 최신화 해야.
  • 50. 50 Kotlin Multiplatform Mobile을 위해 필요한 것 KDoctor KMM을 위해 필요한 환경이 있는지 점검하는 앱.
  • 51. 51
  • 52. 52 Kotlin Multiplatform Mobile을 위해 필요한 것 CocoaPods KMM은 SPM(SwiftPackageManager)를 지원하지 않음. (대체 왜!)
  • 53. 53 Kotlin Multiplatform App으로 새 프로젝트를 만듬.
  • 54. 54 패키지 네임은 안드로이드/자바 앱처럼 도메인의 역순으로 지정함.
  • 55. 55 앱 네임 기본으로 androidApp, iosApp, shared로 앱 네임이 정해짐. iOS framework distribution은 Regular로 Cocoapods -_-을 선택할 수 있음.
  • 56. 56 androidApp 안드로이드 관련 코드는 androidApp 아래 위치함
  • 58. 58 iosApp iOS 관련 코드는 iOSApp에 위치함.
  • 60. 60
  • 61. 61 버전 처리는 어떻게 했을까요? expect와 actual shared/src/ commonMain iOS와 Android에서 모두 사용할 인터페이스를 expect 키워드로 만듬.
  • 62. 62 버전 처리는 어떻게 했을까요? expect와 actual shared/src/ androidMain Android의 구현을 actual 키워드를 붙여 구현
  • 63. 63 버전 처리는 어떻게 했을까요? expect와 actual shared/src/ iOSMain iOS의 구현을 actual 키워드를 붙여 구현
  • 64. 64 KMM for iOS에서 만나게 되는 상황들 ObjC 현재 Kotlin은 ObjC만 지원해서 제너릭 클래스만 지원하고 인터페이스를 지원하지 못함. Abstract class를 대신 사용해야 함. @HinddenFromObjC, @ObjcName 키워드를 적극적으로 활용하자. @ObjcName(swiftName=“_”) _는 특수한 키워드. plane.fuel(volume: .Gallos(gallos: 12.5)) 대신 plane.fuel(.Gallons(12.5)) 장기적으로는 코트린이 Swift를 바로 타게팅할 것임. Swift를 ObjeC를 제외하고 바인드할 수 없었기에 발 생한 문제. SourceKitten와 같은 도구들로 중간 코드를 생성하자. 라인 데메에카이 겪은 어려움 Suspend suspend는 콜백(completion handler)이 되고 콜백은 Swift에서 async로 호출 가능하지만 취소가 불 가능함. Flow도 잘 지원되지 않음. KMP-NativeCoroutines 라이브러리를 활용해야 함. https://github.com/rickclephas/KMP-NativeCoroutines 코틀린 예외가 스위프트 핸들러 전달 되지 않을 수 있어 @Throws 키워드로 Error를 지정해야 함.
  • 65. 65 KMM for iOS에서 만나게 되는 상황들 CocoaPods 아직 공식적으로 SPM(Swift Package Manager)를 지원하지 않음. Gradle API 수준에서 정리된 이후 에 지원한다고 함. (언제?) CocoaPods는 의존성을 소스로 가져와 같이 빌드에 사용하기에 매우 비효율적. TouchLab의 라이브러리 KMMBridge를 사용합시다. https://github.com/touchlab/KMMBridge SPM을 대응하기 위해서는 Git 리포지토리와 스태틱 파일 저장소가 필요하다. (AWS?) Frozen Global Object는 기본으로 frozen. 접근할 수 있지만 변경할 수 없음. @ThreadLocal을 붙이면 freeze 호출 안함. Atomic한 자료구조의 사용이 필요할 수 있다. freeze() 확장 함수를 이용해 데이터를 얼릴 수 있고 풀 수는 없음. Global 프로퍼티는 메인스레드에서만 볼 수 있음.
  • 66. 66 KMM for iOS에서 만나게 되는 상황들 Memory Management 스택 트레이스 디버깅 어렵고, 메모리 매니지먼트가 아직 안정적이지는 않음. https://youtrack.jetbrains.com/issue/KT-55512 참고 Kotlin Multiplatform Mobile을 활용한 데마에칸 드라이버앱 개발 이야기 Kotlin/Multiplatform for iOS developers : state & future by Salomon Brys
  • 68. 68 Compose Multiplatform mobile application 템플릿을 이용해서 시작해야 템플릿 https://github.com/JetBrains/compose-multiplatform-ios-android-template
  • 69. 69 Compose for iOS를 위해 필요한 것 Android Studio Android 앱과 iOS 앱를 실행할 수 있는 개발 환경. Xcode Xcode는 백그라운드에서 수행 됨. Kotlin/Native가 의존하는 버전을 설치해야 함. Kotlin Multiplatform Mobile 안드로이드 스튜디오에서 Kotlin Multiplatform Mobile 플러그인 설치. CocoaPods Compose for iOS도 SPM(SwiftPackageManager)를 지원하지 않음.
  • 70. 70 Compose for iOS를 위해 필요한 것
  • 76. 76 처음 변경해보는 Compose for iOS TextField 추가 TextField를 추가하는 데모를 합시다.
  • 77. 4. Compose for Desktop
  • 78. 78 Compose for Desktop의 특징 Cross- Platform 멀티플랫폼이 아닌 크로스플랫폼으로 분류. JVM이 타겟이고 JVM 덕에 여러 플랫폼에서 도는 것을 크로스플랫폼으로 설명. SKIKO SKIA의 코틀린 바인딩 SKIKO에 의해 렌더링. https://github.com/JetBrains/skiko SKIA의 폰트 렌더링이 운영체제 마다 달라 스크린 샷 테스트를 하지 말자. Compose Multiplatform IDE support 인텔리제이 아이디어나 안드로이드 스튜디오에 설치. https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support IntelliJ IDEA 인텔리제이 아이디어 2020.3 이상에서 사용가능.
  • 79. 79 Compose for Desktop의 특징 참고영상 You can do desktop too! By Victor Kropp https://www.youtube.com/watch?v=Mgf_9kxM1BA JDK 15 JDK11으로 프로젝트 생성 가능. 네이티브 배포 패키징을 위해서는 15 이상.
  • 80. 80 Compose Multiplatform desktop application New Project로 시작하기
  • 81. 81
  • 82. 82
  • 84. 84 Compose for Web의 특징 WebAssembly JavaScript를 쓰지 않고 WebAssembly로 실행. Kotlin/WASM이 타겟. Compose HTML HTML을 생성하는 Kotlin/JS의 라이브러리도 있음. Compose for Web과 무관. Compose Multiplatform IDE support 인텔리제이 아이디어나 안드로이드 스튜디오에 설치. https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support IntelliJ IDEA 인텔리제이 아이디어 2020.3 이상에서 사용가능.
  • 86. 86
  • 87. 87
  • 88.