kotlin 스럽다는 것

조갱·2022년 5월 14일
1

kotlin

목록 보기
4/12

내 입사 동기들은 항상 kotlin 스러운에 집착한다.

kotlin을 사용한지 4개월정도 된 지금 시점에서, kotlin 스럽다에 대해 적어보고자 한다.

시작하기 전에

JAVA vs Kotlin 을 통해 두 언어의 차이점을 들어보자.

이런 간단한 학사 정보 시스템이 있다고 하자. (실제로 학사 관리 시스템은 무척 복잡하다.)
학생들의 정보는 students : List<Student>로 저장된다.
방방대학교는 평균 점수가 가장 높은 학생에게 장학금을 지급하고자 한다.

1. 평균 점수가 가장 높은 학생 찾기

학생 정보 :
김철수 (C언어: 100점, 컴퓨터구조: 80점)
김영희 (C언어: 80점, 자료구조: 80점)
김민수 (C언어: 80점, 대학글쓰기: 90점, 이산수학: 90점)

Java

Student maxStudent = null;
for (Student student : students) {
    if (maxStudent == null) {
        maxStudent = student;
    } else if (maxStudent.getScoreAvg() < student.getScoreAvg()) {
        maxStudent = student;
    }
}

또는

Student maxStudent = Collections.max(students, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getScoreAvg().compareTo(o2.getScoreAvg());
    }
});

Kotlin

val maxStudent = students.maxByOrNull { it.scoreAvg }

(Java 코드가 약간은 억지스럽긴 하지만) Java코드에 비해 Kotlin에서는 1줄만에 해결된다.
두 코드 모두 김철수의 Student객체가 반환된다.

2. 총점이 같은 경우

민수가 대학글쓰기의 점수가 마음에 안들었던 모양인지, 이의제기를 신청했다.
(다행히도) 채점에 문제가 있던걸 발견한 교수님은, 민수의 대학글쓰기 성적을 100점으로 올려주었다. (잘못 채점했군요. 민수 학생의 점수는 70점입니다.)

학생 정보 :
김철수 (C언어: 100점, 컴퓨터구조: 80점)
김영희 (C언어: 80점, 자료구조: 80점)
김민수 (C언어: 80점, 대학글쓰기: 100점, 이산수학: 90점)

이제 철수와 민수의 평균은 90점으로 동일하다.
철수와 민수 중 누구에게 장학금을 지급할지 고민하던 학교는, 이수한 과목 수가 더 많은 학생에게 장학금을 지급하고자 한다.

Java

Student maxStudent = null;
for (Student student : students) {
    if (maxStudent == null) {
        maxStudent = student;
    } else if (maxStudent.getScoreAvg() < student.getScoreAvg()) {
        maxStudent = student;
    } else if (maxStudent.getScoreAvg().equals(student.getScoreAvg())) {
        if (maxStudent.subjects.size() < student.subjects.size()) {
            maxStudent = student;
        }
    }
}

또는

Student maxStudent = Collections.max(students, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.getScoreAvg().equals(o2.getScoreAvg())) {
            return o1.subjects.size() - o2.subjects.size();
        } else {
            return o1.getScoreAvg().compareTo(o2.getScoreAvg());
        }
    }
});

Kotlin

val maxStudent = students.sortedWith(compareByDescending<Student> { it.scoreAvg }.thenByDescending { it.subjects.size })
            .firstOrNull()

kotlin도 아까보단 지저분해진 감이 있지만,, java코드에 비해서는 덜 지저분해졌다.

위 예시는 정말 빙산의 일각이고, Java/C# -> Kotlin 으로 넘어온 경험자로써, Kotlin은 (잘만 쓰면) 정말 없는거 빼고 다있는 간단한 언어라고 생각한다.



Kotlin 스럽다는 것?

내가 생각하는 kotlin 스럽다의 정의는 아래와 같다.

함수형 프로그래밍 언어에 대한 이해와, kotlin에서 지원하는 기능/메소드를 적절하게 사용하는 것


Kotlin 언어의 특징

  • Kotlin은 함수형 언어와 객체지향 언어를 동시에 지원하는 혼합형 패러다임이다.
  • Kotlin은 Java코드를 완벽하게 지원한다. 실제로 런타임 시에도 Kotlin -> Java로 변환하여 동작한다. (Java -> Kotlin으로 변환은, IntelliJ 기준으로 IDE 에 붙여넣기만 하면 변환 여부를 선택할 수 있다.)
    Kotlin 코드를 java 로, java 코드를 Kotlin으로 변환하기


명령형 프로그래밍과 선언형 프로그래밍

명령형 프로그래밍 (How)

프로그램의 상태와 상태 변경을 시키는 '구문'의 관점에서 연산을 설명하는 방식
그래서, 너가 하고싶은걸 '어떻게' 해결할건데!

  • 절차적 프로그래밍: 수행되어야 할 연속적인 계산 과정을 포함하는 방식
    ex ) C, Cobol, Fortran
  • 객체지향 프로그래밍: 객체들의 집합으로 프로그램의 상호작용을 표현
    ex ) Java, C++

선언형 프로그래밍 (What)

어떤 방식(How)가 아닌 무엇(What)과 같은지를 설명하는 방식
그래서, 너가 '무엇'을 할건데!

  • 함수형 프로그래밍: 순수함수를 보조함수와 조합하는 방식
    ex ) Kotlin, LISP, Prolog



함수형 언어

  • 자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임의 하나
  • 명령형 프로그래밍에서는 상태를 바꾸는 것을 강조하는 것과는 달리, 함수형 프로그래밍은 함수의 응용을 강조
  • 프로그래밍이 문이 아닌 식이나 선언으로 수행되는 선언형 프로그래밍 패러다임을 따르고 있다
  • 함수형 프로그래밍은 1930년대에 계산가능성, 결정문제, 함수정의, 함수응용과 재귀를 연구하기 위해 개발된 형식체계인 람다 대수에 근간을 두고 있다.
  • 다수의 함수형 프로그래밍 언어들은 람다 연산을 발전시킨 것으로 볼 수 있다.



순수 함수와 함수 조합

순수 함수

  • 동일한 입력에는 항상 같은 값을 반환해야 하는 함수
  • 함수의 실행이 프로그램의 실행에 영향을 미치지 않아야 하는 함수
  • 함수 내부에서 인자의 값을 변경하거나 프로그램 상태를 변경하는 Side Effect가 없는 것
// 일반 함수
var num: Int = 0

fun add(param: Int) {
    return num + param
} // add()를 수행하면 num의 값이 변경되므로 순수함수가 아니다.

// 순수 함수
fun add(param1: Int, param2: Int){
	return param1 + param2
} // 인자만 받아서 값을 반환하므로, side-effect가 없는 순수함수이다.

함수 조합

  • 작은 순수 함수들을 조합하여 큰 함수들을 만드는 것
  • 함수의 파라미터로 함수를 받아 엮어 사용하기 때문에, 고차원 함수가 필요하다.
  • 이 때문에 람다 함수가 많이 사용된다.



Why 코틀린 스러워야 할까?

  1. 빠른 생산성
  2. 코드가 가볍다.
  3. 가독성이 높다.

위 기준은 내 기준이라 절대적이지는 않을 수 있다.
이미 구현된 메소드로 '무엇을 할 지'만 명시하면 되기 때문에, 로직을 별도로 짤 필요가 없다.
또한, 로직을 별도로 짜지 않아도 되기 때문에 (적어도 비즈니스 로직 단은) 코드가 가벼우며,
코드가 곧 주석이 되는 느낌이 있어 가독성이 높아진다. (실제로 우리 실무 코드에는 주석이 거의 없다.)

물론 순수 함수를 짜는 것은 힘든 일이다. 분명 나는 제일 작은 단위로 쪼개서 순수함수를 만들었다고 생각하지만, 그 순수함수를 더 쪼갤 수도 있는 상황이며, 어디까지 쪼개야 할지도 큰 고민이다.

하지만, 코틀린은 확장 함수 (Extension Function)을 지원하기 때문에, 이러한 부분이 어느정도는 해소될 수 있다고 생각한다.

How 코틀린 스러울 수 있을까?

코틀린 서적을 정독하는 것은 아주 큰 도움이 될 것 같다.

코틀린스럽게 짜고 싶지만, 어떤 기능이 있는지 잘 모르는 것이 '코틀린 스럽게 짜는 것'의 가장 큰 장벽이라고 생각한다.
보통은 내가 원하는 기능을 검색하면 나오기는 하지만, 가끔은 '이런거는 없겠지' 생각하며 자바처럼 구현하곤 한다. (forEach 돌리면서..)
근데 (놀랍게도) 알고보면 kotlin에 기본적으로 있는 메소드이다 ㅋㅋ.

그래서 나는 앞으로 Kotlin In Action 책을 정독하면서 블로그에 내용을 정리해볼까 한다.

여담이지만, 하도 Kotlin에 익숙해지다보니 이전에 쓰던 Java와 C#이 어색해졌다. 더 어색해지지 않게 계속 사용하겠지만, Kotlin 스러우면 그만큼 사용하기 편리하다.

Reference :
함수형 언어 : https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D
명령형 프로그래밍과 선언형 프로그래밍 :
https://okayoon.tistory.com/entry/프로그래밍-패러다임명령형-프로그램절자적-객채지향-선언형-프로그램함수형의-정의-특징-비교를-간단히-알아가자
함수형 프로그래밍이란? : https://jongminfire.dev/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80
함수형 프로그래밍 :
https://velog.io/@thms200/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

profile
A fast learner.

0개의 댓글