Kotlin in Action 1. Kotlin: what and why

20 Mar 2019 - breadkey

1. Kotlin: what and why

자바 플랫폼에서 돌아가는 새로운 프로그래밍 언어이다. 간결하고 실용적이며, 자바 코드와의 상호운용성을 중시한다. 즉, 모든 자바 라이브러리나 프레임워크를 코틀린에서도 사용할 수 있다.

1.1 코틀린 맛보기

// '데이터' 클래스
data class Person (
    // 프로퍼티
    val name: String,
    val age: Int? = null
)

// 최상위 함수
fun main (args: Array<String>) {
    val persons = listOf(
        Person("영희"),
        Person("철수", 
            // 이름이 붙은 파라미터
            age = 29)
    )

    val oldest = persons.maxBy { 
        // 람다 식과 "엘비스" 연산자
        it.age ?: 0 
    }
    
    // 스트링 템플릿
    println("나이가 가장 많은사람: $oldest")
}

// 결과: 나이가 가장 많은사람: Person(name=철수, age=29) 

name과 age라는 프로퍼티가 들어간 간단한 data class를 정의하고 있다.

age 프로퍼티를 보면 타입이 Int?인데 값을 정하지 않아도 되는(nullable) 타입이다. 또한 기본값을 null로 지정하고 있다. 밑에 psersons 리스트를 만들 때 영희의 나이는 null이 된다.

가장 나이가 많은 사람을 찾기 위해 maxBy 함수를 사용하는데, labmda식은 Person 파라미터를 받는다. Person 파라미터는 별도의 이름을 지정하지 않아도 it이라는 이름을 통해 사용할 수 있다. ?: 0 이라는 elvis 연산자는 null을 0으로 변한해주어 Person 오브젝트들의 나이를 비교할 수 있게 된다.

1.2 코틀린의 주요 특성

1.2.1 대상 플랫폼: 서버, 안드로이등 자바가 실행되는 모든 곳

가장 일반적으로 백엔드, 안드로이드 모바일 애플리케이션에서 실행되지만 인텔의 멀티OS 엔진을 사용하면 iOS에서도 사용할 수 있고, 토네이도FX나 자바FX 등을 사용해 데스크탑 애플리케이션도 작성할 수 있다. 코틀린 1.1부터 자바스크립트도 공식적으로 지원한다.

코틀린은 일부만을 다루기 위한 언어가 아니다!

1.2.2 정적 타입 지정 언어

정적 타입 지정은 컴파일할 때 구성요소들의 타입을 알 수 있고 컴파일러가 검증해 준다.

그러나 자바와 달리 변수의 타입을 코틀린에서는 명시하지 않아도 된다. 컴파일러가 문맥에서 타입을 유추해주기 때문이다. 이런 기능을 타입 추론(type inference)라고 한다.

정적 타입 지정의 장점은 다음과 같다.

  • 성능
    실행 시점에 어떤 메소드를 호출할지 알아내는 과정이 필요 없으므로 메소드 호출이 더 빠르다.
  • 신뢰성
    컴파일러가 프로그램의 정확성(corectness)을 검증하기 때문에 실행 시 프로그램이 오류로 중단될 가능성이 더 적어진다.
  • 유지 보수성
    코드에서 다루는 객체가 어떤 타입에 속하는지 알 수 있기 때문에 처음 보는 코드를 다룰 때도 쉽다.
  • 도구 지원
    정적 타입 지정을 활용하면 더 안전하게 리팩토링할 수 있고, 도구는 더 정확한 코드 자동완성 기능 및 IDE의 다른 기능들을 더 잘 만들 수 있다.

타입 추론 기능은 타입 선언을 직접 해야하는 불편함을 해소해 준다.

class, interface, generics는 모두 자바와 비슷하게 작동하므로 자바에 대해 아는 내용을 코틀린에 적용할 수 있다.

자바와 다른 새로운 점 중 중요한 특성은 nullable 타입을 지원한다는 점이다. 이에 따라 컴파일할 때 null pointer execption이 발생할 수 있는지 여부를 검사할 수 있어서 더 신뢰성을 높혀줄 수 있다.

함수형 프로그래밍을 지원하여 함수 타입에 대해서도 지원해준다.

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

  • fist-class 함수
    함수를 일반 값처럼 다룰 수 있다. 함수를 변수에 저장할 수 있고 함수를 다른 함수에 전달할 수 있으며, 함수에서 새로운 함수를 만들어 반환할 수 있다.
  • 불변성(immutability)
    함수형 프로그래밍에서는 일단 만들어지고 나면 내부 상태가 절대로 바뀌지 않는 불변 객체를 사용해 프로그램을 작성한다.
  • 부수 효과(side effect) 없음
    입력이 같으면 출력이 같고 다른 객체의 상태를 변경하지 않으며 외부와 상호작용하지 않는 순수 함수를 사용한다.

이런 핵심개념들로 작성한 코드는 간결하며 우아하다. 함수를 값처럼 활용하여 더 강력한 추상화를 할 수 있어코드 중복을 막을 수 있다.

fun findAlice() = findPerson { it.name == "Alice "}
fun findBob() = findPerson { it.name = "Bob" }

위 두 함수처럼 매우 비슷한 기능(사람 찾기)을 하지만 세부 사항(Alice, Bob)이 다른 함수를 공통 로직 함수(findPerson)를 뽑아내 사용하고 서로 다른 세부사항(it.name == ?)은 인자로 전달할 수 있다. 또한 인자는 그 자체가 함수다. 위처럼 lambda식을 사용하여 매우 간결하게 표혈할 수 있다.

함수형 프로그래밍은 불변 데이터 구조를 사용하고 순수 함수를 그에 적용한다면 복잡한 동기화를 하지 않아도 되므로 다중 스레드를 사용해도 매우 안전하다(safe multithreading).

부수 효과가 필요한 함수는 그 함수를 실행할 때 필요한 전체 환경을 구성하는 준비(setup)가 필요하지만, 순수함수는 그런 준비 없이 독립적으로 테스트할 수 있으므로 함수형 프로그래밍은 테스트하기 매우 쉽다.

함수형 프로그래밍 스타일은 언어와 관계없이 활용할 수 있다. 자바 8 이전의 자바에서는 함수형 프로그래밍을 지원할 수 있는 기능이 거의 없었지만, 코틀린은 처음부터 매우 풍부하게 지원해 왔다.

  • 함수 타입을 지원함에 따라 어떤 함수가 다른 함수를 파라미터로 받거나 함수가 새로운 함수를 반환할 수 있다.
  • 람다 식을 지원함에 따라 번거로운 준비 코드를 작성하지 않아도 코드 블록을 쉽게 정의하고 여기저기 전달할 수 있다.
  • 데이터 클래스는 불변적인 VO를 간편하게 만들 수 있는 구문을 제공한다.
  • 코틀린 표준 라이브러리는 객체와 컬렉션을 함수형 스타일로 다룰 수 있는 API를 제공한다.

코틀린은 상황에 맞게 명령형, 함수형 방식을 선택해서 사용할 수 있다.

1.2.4 무료 오픈소스

코틀린 언어와 컴파일러, 라이브러리 및 코틀린과 관련된 모든 도구는 모두 오픈소스이며 개발은 깃허브에서 이루어진다.

1.3 코틀린 응용

1.3.1 코틀린 서버 프로그래밍

  • 브라우저에 HTML 페이지를 돌려주는 웹 애플리케이션
  • 모바일 애플리케이션에게 HTTP를 통해 JSON API를 제공하는 백엔드 애플리케이션
  • RPC 프로토콜을 통해 서로 통신하는 작은 서비스들로 이루어진 마이크로서비스 서버 프로그래밍은 위와 같은 응용분야를 포함하고 있는 매우 광범위한 개념이다. 개발자들은 위와 같은 애플리케이션들을 수년간 개발해 오면서 개발에 도움을 줄 수 있는 기술과 프레임워크를 엄청나게 만들어왔다. 또한 새로운 기술이나 프레임워크는 언제나 기존 프레임워크나 기술을 확장하고 개선하거나 대치하며, 이미 여러 해 동안 쓰여 온 기존 시스템과 새로운 코드를 통합해야 한다. 이런 상황에서 자바 코드와 매끄럽게 상호운용할 수 있는 코틀린의 특징은 커다란 장점이다. 코틀린은 새로운 컴포넌트를 작성하거나 기존 컴포넌트를 코틀린으로 이식하는 경우 모두 잘 들어맞는다. 자바 클래스를 코틀린을 확장해도 아무런 문제가 없으며, 코틀린 클래스 안의 메서드나 필드에 자바 어노테이션을 붙여야 하는 경우에도 아무런 문제가 없다.

코틀린을 사용하면 몇 가지 새로운 기술을 활용해 서버 시스템을 개발할 수 있다.

tag: kotlin

Related Posts