The light side of force will be with you
인류의 언어에서 마침표는 끝을 의미하며, 제아무리 온갖 미사여구로 치장된 문장이라 할지라도, 마침표를 만나는 순간 쓸쓸히 무대의 뒤편으로 퇴장해야만 한다.
프로그래밍 언어에서의 문장(statement)은 그 자체로 종결성을 가지기에 값을 반환하지 않는다.
if (…) { … }
만약 if와 같은 문장이 반환값을 가지게 되면, 문장이 아닌 표현식(expression)이 된다.
val newYearAge = if (…) { age + 1 } else 0
표현식은 그 자체로 값을 나타내는데, 위 예시의 if 처럼 큰 덩어리의 표현식만 존재하는 것은 아니다. 예를 들어 age + 1 또한 덧셈 표현식이며, 위의 예시는 if 표현식과 덧셈 표현식이 연결되어 있는 좀 더 큰 표현식이다. 즉, 표현식은 조립가능성(compsability)이 높다. 반대로 문장은 조립가능성(composability)이 없다.
이러한 이유로 문장은 어쩔 수 없이 사이드 이펙트(side effect)를 발생시켜야만 존재의 가치를 인정받는다. 만약 문장으로 기능하는 if 구문이 아래의 형태라면 사실 그 어떤 유의미성도 찾을 수 없다.
if (true) { age + 1 } else { age }
따라서 위의 if 구문은, 최소한 구문 바깥의 외부 변수에라도 사이드 이펙트를 만들어야만 한다.
var newYearAge
if (true) { newYearAge = age + 1 } else { newYearAge = age }
이러한 이유로 문장은 사이드 이펙트를 갈망하며, 가변성(mutability)은 피할 수 없는 운명이라는 핑계를 댄다. 그 핑계의 증거가 바로 가변 타입(var) 변수의 선언이다. 그리고 사이드 이펙트를 만들어야만 생명을 영위할 수 있다는 것, 이것이 바로 문장의 다크 사이드다.
그런데 만약 위의 if 구문이 표현식으로 전환된다면, 그 반대의 효과를 누리게 된다.
val newYearAge = if (true) { age + 1 } else { age }
표현식 if가 값을 반환하기 때문에, 그 값을 다음 코드로 연결시킬 수 있으며, 따라서 if 표현식의 바깥에서 불변 타입(val) 변수를 선언할 수 있었으며, 코드의 불변성(immutability)은 높아진다.
함수형 프로그래밍(FP)에서는 함수의 순수성(purity)을 중요하게 생각하는데, 이러한 순수성을 지키기 위해서는 무엇보다도 사이드 이펙트의 통제가 중요하다. 문장은 사이드 이펙트의 유혹에서 벗어날 수 없는 태생적 한계가 있다면, 표현식은 이러한 유혹에서 자유롭다.
이러한 이유로 코틀린은 스스로를 표현 지향 언어(eop language)라고 말하며, 자바에서는 문장이었던 문법적 요소들을 표현식으로 전환하였다. 그리고 코틀린의 고수들은 “더 많은 표현, 더 적은 문장(more expressions, fewer statements)“으로 향하는 코드를 작성하게 된다.
더 나은 프로그래머가 되고 싶은가? 그렇다면 fewer statements의 제약(constraint)을 실험해 보는 건 어떤가?
disclaimer
이 글의 핵심 내용은 programming kotlin에서 가져온 표현이다.