개발+IT

Kotlin/Everywhere Seoul 2019에 다녀왔다.

스베틀라나 이사코바 선생 뵈러 감

지난 26일 전 세계적으로 열리게 될 펼치게 되는 Kotlin/Everywhere가 GDG Seoul 주최로 서울에서도 열렸다. 갈까 말까 고민이 많았는데, Kotlin in Action의 공동 저자이자 JetBrains의 Developer Advocate인 스베틀라나 이사코바가 와서 직접 강연을 한다는 얘길 듣고 뭔 강연인지도 확인하지 않고(뭐 좋은 얘기 하겠지...) 바로 신청했다. 

신청해놓고 강연 제목을 확인해보니 'What's new in Kotlin'이다. 통역이 제공되지 않긴 하지만 뭐 적당히 알아들을 수 있는 것만 듣지 하는 생각으로 ㄱㄱ했다. 여튼 제목으로 미루어볼때 코틀린이 앞으로 어떻게 발전해나갈 것인지에 대한 얘기겠거니 했는데 역시나 그랬다. 혹시 발표자료가 궁금한 분이 있다면 일본에서 열렸던 Kotlin Fest Tokyo 2019와 동일한 자료를 사용했다고 하니 하단의 링크를 클릭하길 바란다. 그 아래에는 강연 내용 요약(제대로 듣지 못한 내용이 있을수 있으니 양해를 부탁한다).

Agenda1. Kotlin Evolution

코틀린의 역사를 간략히 읊고 난 후, 코틀린이 발전하기 위해서 어떤 일을 하고 있는지에 대한 이야기로 본론을 시작했다.

Keeping Modern

코틀린이 모던한 언어로 유지되길 바라는 것 같았다. 이를 위해 Github에 KEEP(Kotlin Evolution and Enhancement Process)이라는 저장소를 운영하고 있는데, 이 곳에서 새로운 기능이 제안되고 또 논의되는 모습을 확인할 수 있다. 실제로 여기서 제안됐던 기능들이 현재 코틀린 기능으로 꽤 들어갔다고 알고 있다.

Comfortable Update

버전이 올라가면서 이를 적용하는게 편하기를 바라며, 그러기 위해 노력하고 있다고 한다. IDE를 통해 자동으로 마이그레이션되는 기능과 더불어 자동 마이그레이션이 놓치는 부분을 위해 Deprecation된 것들을 확실하게 알 수 있도록 한다고...

Feedback Loop

단순하다. 코틀린 개발팀에서는 커뮤니티를 통한 피드백을 환영한다. 코틀린은 커뮤니티를 사랑한다는 얘길 했다.

Agenda2. Exeperimental Features

앞의 Agenda1은 아무대로 서론이라고 볼 수 있었고, 실제로는 이 실험 기능들에 대한 내용이 본론이라고 생각한다. 코틀린에는 Experimental 이라고 해서 실험적으로 도입되는 기능이 있다. 앞으로 사라질 수도 있고, 내용이 바뀔수도 있는 기능인데 얼리어답터 프로그래머들을 위해 빌드 설정을 통해 미리 사용해볼 수 있다. 참고로 Experimental API를 직접 만들 수도 있다. 

이런 식이다. 포스팅 위에 넣어둔 링크의 슬라이드에 있는 내용이다.

여튼 Agenda2에서는 이런 실험 기능들 중 중요한 기능을 몇가지 소개시켜줬다.

Inline Classes

어떤 값을 넘기는데 값 자체가 아니라 래퍼 클래스로 감싸서 넘겨야 하는 경우가 있다. 이런 경우에 클래스를 만드는 것으로 인해 추가적으로 생기는 오버헤드를 막기 위한 기능이다. 예를 들어 String 값을 넘겨야 하는데 그냥 넘길수 없고 래퍼 클래스가 필요한 상황이다. 이때 다음과 같이 작성해서 쓸 수 있다.

그런데 이게 어떻게 오버헤드를 줄여주는가? 하면 실제로 저 구문이 동작할 때는 fun useSomeString(ssrt: String) 과 같은 식으로 동작한다고 한다. 실제로 이 날 강연에서는 Duration API를 예시로 들었다(참고로 Duration API도 실험기능이며, Inline Class를 활용하는 기능이라고 한다). 강연 슬라이드를 보면 알겠지만, 값을 감싸는 래퍼 클래스를 만들어서 생기는 오버헤드를 줄이는 것만 아니라 코드의 의미를 명확하게 만들어 주는 역할도 해주게 되는 것이 괜찮아보였다.

다만 아직 제약이 있는데, 인라인 클래스에는 단 하나의 val 프로퍼티만 정의할 수 있다.

Contract

이 기능은 특정 함수가 동작하는데 있어 컴파일러에게 몇가지 추가 정보를 전달해주는 기능이다. 예를 들어 String.isNullOrEmpty 함수를 수행할 때 이 함수가 true를 반환할 경우 해당 String값이 Null이 아닌 것을 프로그래머는 알겠지만 컴파일러는 알 수 없는데, 이 정보를 컴파일러가 알 수 있게 해주자는 것이다. Nullable 값을 Not Null 값으로 언래핑 하는 것 만으로도 코딩하는데 있어 꽤 간편한 데 이 기능까지 추가되면 아마 더 편리하게 프로그램 개발을 할 수 있을 것 같았다(그놈의 Null...).

Immutable Collections

코틀린의 Collection은 이미 값을 변경할 수 없도록 되어있지만(변경할 수 있는 Collection는 MutableCollection인 식), 이 Collection은 Read-Only인 것이지 완전히 Immutable 한 것은 아니다. 예를 들어 다음과 같은 경우가 그렇다.

위의 코드에서 ListWrapper.readOnly는 분명히 값에 접근만 할 수 있다. 하지만 Immutable한가? ListWrapper에서 특정 함수를 작동시켜 mutable의 값을 바꾸면 readOnly에서 읽어들일수 있는 값 역시 변경되는 것이기 때문에 Immutable하다고 할 수 없다.

이를 위해 List를 구현하는 ImmutableList와 ImmutableList 상속(구현?)하는 PersistentList가 존재한다고 한다. ImmutableList는 실제로 Immutable한 녀석이고, PersistentList는 값의 변경을 지원하는 녀석이다. 다만 PersistentList의 값을 변경하는 함수를 수행하면 PersistentList 자체가 변하는 것은 아니고 해당 변경사항이 적용된 새 List가 반환된다고 한다. 그러나 또 실제로는 새롭게 생성되는 List역시 완전히 새롭지는 않고 원본 PersistentList의 데이터를 공유하는 식이라고. 그리고 또한 계속해서 새 List가 반환되는 오버헤드를 막기 위해 builder 패턴을 지원한다고 한다.

Flows

Flows를 한마디로 정의하면 다음과 같다

Suspend based Reactive Stream

무슨 소린고 하니, Coroutine의 suspend 함수를 기반으로 하여 반응형 스트림 API를 구현한 것이라는 것이다. 이 대목에서 RxJava를 생각하지 않을 수 없는데, 코틀린 개발팀에서도 이를 신경쓰고 있는지 코틀린의 Flow와 RxJava의 Publisher가 각각 서로로 변환할 수 있는 확장함수를 제공한다고 한다. 또한 Backpressure 역시 자체 suspension 메커니즘에 의해 자동으로 수행된다고.

이 내용을 듣고 있자니 Swift에 도입될 Combine API가 생각나지 않을 수가 없었다. 처음에 Swift Combine API가 공개되었을때 ReactiveSwift 진영이었나 RxSwift 진영이었나에 있는 개발자가 트위터에 자기는 직업을 잃었다 라는 말을 했었는데, 그 때는 또 그렇군 싶었지만 Flows까지 보고 있자니 모바일 클라이언트 프로그래밍에 있어서 반응형 프로그래밍이 갖는 의의가 정말 어마어마하게 커졌구나 싶었다. 일종의 유행? 경향성 문제인건가 싶기도 한데, 왜냐면 최근에 SwiftUI와 Kotlin Composer가 비슷한 시기에 공개된 것을 보면서(그리고 플러터의 선언형 UI 문법을 보면서) 앞으로 모바일 클라이언트 프로그래밍에서 UI를 만드는 일은 대부분 선언형으로 가려나 했던 것도 생각났거든. 안드로이드나 iOS의 보안 정책, 그리고 UI 컴포넌트의 특성이 묘하게 서로를 닮아간다는 생각을 했었는데 주 사용 언어까지 이렇게 가고 있으니 참 재미있다.

Multiplatform Projects

플러터나 리액트 네이티브와 같은 대부분의 멀티플랫폼(아니 사실은 크로스 플랫폼) 프로젝트는 UI까지 포함하는 성격의 멀티플랫폼 프로젝트인데, 코틀린 개발팀에서 말하는 코틀린 멀티플랫폼 프로젝트는 그런 것이 아니었다. 서버(Kotlin/JVM) - 안드로이드(Kotlin/JVM) - iOS(Kotlin/Native) - WebBrowser(Kotlin/JS) 로 온갖 플랫폼을 가로지르는 공통 코드를 생각하는 것이었다. 여기서 말하는 공통 코드란

  • 비즈니스 로직의 공유
  • UI 플랫폼으로부터 독립적
  • The shared part might vary(공유되는 부분은 조금씩 다를 수 있다? 무슨 말인지 잘 모르겠음)

라는 것이다. 이것이 실제로 어떻게 구현되는가를 보면,

  • expect 키워드를 통해 사용될 공통 코드를 정의하고 사용할 수 있고,
  • actual 키워드를 통해 각각의 플랫폼에서 실제로 구동되는 구현

을 만들 수 있다는 것이다. 플랫폼을 가로지르는 인터페이스를 보는 기분이었다(아마 실제로는 어떨지 모르겠지만). 실제로 코틀린 스탠다드 라이브러리나 Ktor HTTP client와 같은 라이브러리는 코틀린 멀티플랫폼으로 구현된 라이브러리라고 한다. 또한 실제로 프로덕션 레벨에서 코틀린 멀티플랫폼을 사용하고 있다고 하는데, 이에 대한 자세한 이야기는 KotlinConf Copenhagen에서 자세한 얘기를 들을 수 있다고 한다.

또한 멀티플랫폼 얘기를 마무리하면서 이것이 멀티플랫폼에 대처하는 모던한 방법이라는 말을 남겼는데, 꽤 잘 들어맞는 말이라는 생각을 했다. 각각의 플랫폼은 자신들이 쥐고 있는 어떤 주도권을 넘기고 싶어하지 않아하고, 이 때문에 크로스플랫폼 프로젝트가 발전하면 발전할 수록 이들이 따라올 수 있는 플랫폼 독점적인 기능을 OS 차원에서 제공하려고 한다(안드로이드와 iOS에 대한 얘기다). 특히 OS 보안과 UI가 그러한데, 그럴바엔 차라리 비즈니스 로직을 통일할 수 있는 방법으로 접근하는게 더 좋지 않을까? 물론 더 시간이 지나봐야 알겠지만...

스베틀라나 이사코바가 강연을 시작하기 전에 사람들의 코틀린 활용도에 대해 간략히 물어보았는데 코루틴을 쓰는 사람은 많았지만 멀티플랫폼을 그리 많지 않았었다(하나도 없었던 것 같다). 뭐 아무래도 과감하게 도입하기에는 좀 꺼려지는 부분이 있을수 있으니까... 그래도 작은 프로젝트를 진행한다면 한번 도입해보는 것도 고민해볼 만 하지 않나 싶다.

사족

Coursera에 자바 개발자를 위한 코틀린 코스(현재 무료 코스)가 있다고 한다.

코틀린 플레이그라운드 사이트에서 제공하는 핸즈온 강의가 있다. 

  1. 코루틴 & 채널
  2. 멀티플랫폼
  3. 코틀린 네이티브
  4. 코틀린 멀티플랫폼으로 iOS와 안드로이드를 타게팅 하기 

의 네가지로 이루어져있다.

GAE BAL JA

구본본 님의 창작활동을 응원하고 싶으세요?

hell yeah, world
hell yeah, world
구독자 71
멤버십 가입

0개의 댓글

SNS 계정으로 간편하게 로그인하고 댓글을 남겨주세요.
새로운 알림이 없습니다.