기록하는 습관

[Kotlin In Action]1장 - 코틀린이란 무엇이며, 왜 필요한가? 본문

스터디/Kotlin In Action

[Kotlin In Action]1장 - 코틀린이란 무엇이며, 왜 필요한가?

로그뉴 2023. 1. 16. 19:29

** 이 글은 Kotlin In Action을 읽고 정리한 글입니다. **

 


0. Kotlin 이란?

  • Java 와의 상호운용성을 고려하고 실용성을 갖춘 언어
    • 서버 개발, 안드로이드 개발 등 Java가 사용중인 곳이면 대부분 Kotlin을 사용할 수 있다.
    • Java보다 더 간결한 코드로 편하게 사용 가능하다.

 

1. 정적 타입 지정 언어

  • 모든 프로그램 구성 요소의 타입을 컴파일 시점에 알 수 있고 프로그램 안에서 객체의 필드나 메서드를 사용할 때마다 컴파일러가 타입을 검증해줌
    • 참고) 동적 타입 지정 언어란?
      • 타입과 관계없이 모든 값을 변수에 넣을 수 있다.
      • 메서드나 필드 접근에 대한 검증이 실행 시점에 일어난다.
      • 장점 - 코드가 더 짧아지고 데이터 구조를 더 유연하게 생성하고 사용할 수 있다.
      • 단점 - 이름을 잘못 입력하는 등의 실수를 컴파일 시 걸러내지 못하고 실행 시점에 오류가 발생한다.
  • 타입 추론
    • 코틀린 컴파일러가 문맥을 고려해 변수 타입을 자동으로 유추 (ex. var x = 1)
  • 정적 타입 지정 언어의 장점
    • 성능
      • 실행 시점에 어떤 메서드를 호출할지 알아내는 과정이 필요 없으므로 메서드 호출이 더 빠르다.
    • 신뢰성
      • 컴파일러가 프로그램의 정확성을 검증하기 때문에 실행 시 프로그램이 오류로 중단될 가능성이 더 적어진다.
    • 유지보수성
      • 코드에서 다루는 객체가 어떤 타입에 속하는지 알 수 있기 때문에 처음 보는 코드를 다룰 때도 더 쉽다.
    • 도구 지원
      • 정적 타입 지정을 활용하면 더 안전하게 리팩토링할 수 있고, 도구는 더 정확한 코드 완성 기능을 제공할 수 있으며 IDE의 다른 지원 기능도 더 잘 만들 수 있다.

 

2. 함수형 프로그래밍과 객체지향 프로그래밍

  • 함수형 프로그래밍의 핵심 개념
    • 일급 시민(first-class) 함수
      • 함수를 일반 값처럼 다룰 수 있다.
        • 함수를 변수에 저장
        • 함수를 인자로 다른 함수에 전달
        • 함수에서 새로운 함수를 만들어서 반환
      • Java는 일급 함수가 아니지만, Kotlin은 일급함수이다.
    • 불변성(immutability)
      • 함수형 프로그래밍에서는 불변 객체를 사용해 프로그램을 작성한다.
      • 참고) 불변성을 지키는 코드를 작성하기 위해서는 전역 변수의 사용을 줄이고 객체나 배열의 값을 변경해야 할 때는 함수 내에서 해당 object와 동일한 형태를 가지는 object를 생성하여 변경하면 된다.
    • 부수 효과(side effect) 없음
      • 입력이 같으면 항상 같은 출력
      • 다른 객체의 상태를 변경하지 않는다.
      • 함수 외부나 다른 바깥 환경과 상호작용하지 않는 순수 함수를 사용
  • 함수형 프로그래밍의 장점

1. 간결성

  • 공통부분을 따로 함수로 뽑아내고 서로 다른 세부사항을 인자로 전달하기
  • 함수를 값처럼 활용할 수 있으면 더 강력한 추상화를 할 수 있고 강력한 추상화를 통해 코드 중복을 막을 수 있음
fun findAlice() = findPerson { it.name == "Alice" }
fun findBob() = findPerson { it.name == "Bob" }

2. safe multithreading

  • 일반적으로, 적절한 동기화 없이 여러 thread가 같은 데이터를 변경하게 되면 문제가 발생함
  • 불변 데이터 구조를 사용하고 순수 함수를 그 데이터 구조에 적용한다면 다중 스레드 환경에서 같은 데이터를 여러 스레드가 변경할 수 없다. -> 복잡한 동기화를 적용하지 않아도 됨.

3. 테스트 용이

  • 순수함수는 준비 코드없이 독립적으로 테스트할 수 있다.
    • 준비 코드란, 부수 효과가 있는 함수 실행을 위해 필요한 전체 환경을 구성하는 코드를 의미

 

3. 코틀린 응용

  • 코틀린 서버 프로그래밍
    • 자바 코드와 매끄럽게 상호운용할 수 있다는 점이 코틀린의 큰 장점
      • 자바 클래스를 코틀린으로 확장해도 아무 문제가 없으며 코틀린 클래스 안의 메서드나 필드에 특정 애노테이션을 붙여야 하는 경우에도 아무 문제가 없음
    • 코틀린의 빌더 패턴을 활용하면 간결한 구문을 사용해 객체로 이뤄진 그래프를 쉽게 구축하면서도 코틀린이 제공하는 완전한 추상화와 코드 재활용을 지속적으로 누릴 수 있음
    • DSL 기능 사용하기 (참고: https://taes-k.github.io/2021/09/22/kotlin-dsl/)
fun createSimpleTable() = createHTML().
    table{
        tr{
            td{ 
                +"cell"
            }
        }
    }
  • 코틀린 안드로이드 프로그래밍
    • 애플리케이션 신뢰성이 높아지는 것이 장점
      • 코틀린의 type system은 null 값을 정확히 추적하며 null pointer로 생기는 문제를 줄여준다. Java에서 NullPointerException을 일으키는 유형의 코드는 Kotlin에서 컴파일도 되지 않는다.

 

4. 코틀린의 철학

  • 실용성
    • 실제 문제를 해결하기 위해 만들어진 실용적인 언어
    • 언어의 복잡도가 줄어들고 쉽게 배울 수 있음 (다른 프로그래밍 언어가 채택한 이미 성공적으로 검증된 해법과 기능에 의존)
    • 특정 프로그래밍 스타일이나 패러다임을 사용할 것을 강제로 요구하지 않는다.
  • 간결성
    • getter, setter, 생성자 파라미터를 필드에 대입하기 위한 로직 등 자바에 존재하는 여러 가지 번거로운 준비 코드를 코틀린은 묵시적으로 제공하기 때문에 코틀린 소스 코드는 그런 준비 코드로 인해 지저분해지는 일이 없다.
    • 람다를 지원하기 때문에 작은 코드 블록을 라이브러리 함수에 쉽게 전달할 수 있다.
  • 안정성
    • 프로그래밍 언어가 안전하다는 말은 프로그램에서 발생할 수 있는 오류 중에서 일부 유형의 오류를 프로그램 설계가 원천적으로 방지해준다는 뜻이다.
    • 안정성과 생산성 사이에는 트레이드오프 관계가 있다.
    • 코틀린을 JVM에서 실행한다는 사실이 이미 상당한 안전성을 보장할 수 있다는 뜻.
      • 메모리 안정성 보장, 버퍼 오버플로를 방지, 동적으로 할당한 메모리를 잘못 사용함으로써 발생할 수 있는 다양한 문제 예방
    • NullPointerException이 발생할 수 있는 연산을 사용하는 코드 금지
      • 코틀린의 타입 시스템은 null이 될 수 없는 값을 추적하며 '?' 한글자를 추가하여 어떤 타입이 null이 될 수 있는지 표시한다.
val s: String? = null
val s2: String = ""
    • 코틀린은 ClassCastException을 방지해준다.
      • 어떤 객체의 타입을 검사했고 그 객체가 그 타입에 속한다면 해당 타입의 메서드나 필드 등의 멤버를 별도의 캐스트 없이 사용할 수 있다.
if (value is String) // 타입을 검사한다.
	println(value.toUpperCase()) // 해당 타입의 메서드를 사용한다.
  • 상호운용성
    • 자바 코드에서 코틀린 코드를 호출할 때도 아무런 노력이 필요 없다.
    • 기존 자바 라이브러리를 가능하면 최대한 활용한다.
      • Kotlin에서 Java API를 호출할 때 객체를 감사거나 변환할 필요가 없고, Java에서 Kotlin을 호출할 때도 마찬가지로 아무런 변환이 필요 없다.
    • 코틀린은 자체 컬렉션 라이브러리를 제공하지 않고, 자바 표준 라이브러리 클래스에 의존한다.
      • Java와 Kotlin 소스 파일이 임의로 섞여 있어도 제대로 컴파일 할 수 있다.

 

5. 코틀린 코드 컴파일

  • Kotlin 빌드 과정
    • kotlin도 JVM 위에서 동작하므로 Java와 과정이 비슷한데, 차이점은 Kotlin 파일은 Kotlin compiler를 통해 byte code로 변환되고 이 코드는 Kotlin runtime library에 의존되어 실행한다.
    • Kotlin runtime library란?
      • 코틀린 자체 표준 라이브러리로, Java api를 확장한 내용 등이 있다. 코틀린으로 컴파일한 애플리케이션을 배포할 때 runtime library도 함께 배포해야 한다.

 

  • Kotlin과 Java가 함께 있을 때 컴파일 과정
    • 코틀린 컴파일러가 .kt 파일을 .class(바이트 코드)로 컴파일함. 이 때 java 코드도 함께 로딩된다.
    • 자바 컴파일러가 .java 파일을 .class(바이트 코드)로 컴파일함. 이 때 이미 컴파일된 kotlin의 바이트코드 경로를 class path에 추가하여 컴파일 한다.
      • 코틀린 코드 먼저 컴파일 된 후, (자바 코드 + 컴파일 된 코틀린 코드)가 함께 컴파일 되기 때문에 kotlin에서 java의 어노테이션 프로세서로 생성되는 코드를 사용하면 문제가 된다. (ex. lombok - lombok은 java에서 사용되는 어노테이션으로, 컴파일 시점에 실행된다.)
      • 참고: https://d2.naver.com/helloworld/6685007

Comments