Expression-based 언어란 무엇인가
"Rust는 expression-based language다"라는 말을 자주 듣는다. 단순한 문법 차이처럼 보이지만, 사실은 언어가 코드를 어떻게 바라보는가에 대한 철학의 차이다.
두 가지 패러다임
언어를 크게 두 부류로 나눌 수 있다.
Statement-based (명령 중심)
- 코드 = statement의 나열
- statement는 "동작을 수행"하고, expression은 "값을 만든다"
- 둘이 명확히 분리됨
- 예: C, Java, Python (대부분)
Expression-based (값 중심)
- 코드 = expression의 합성
- 거의 모든 문법 요소가 값을 만든다
- 제어 흐름조차 값을 가짐
- 예: Lisp, ML, Haskell, Rust, Scala
차이가 드러나는 지점
핵심은 if, match, block 같은 제어 구조가 값을 가지느냐다.
// C: if는 statement. 값이 없음
int x;
if (cond) {
x = 5;
} else {
x = 10;
}
C에서는 if가 값을 만들지 않으니 변수에 직접 할당이 불가능하다. 그래서 삼항연산자 ?:라는 별도의 expression 버전을 따로 만들어 두었다.
// Rust: if는 expression. 값을 가짐
let x = if cond { 5 } else { 10 };
Rust는 if 자체가 expression이라 별도의 삼항연산자가 필요 없다. match, loop, block { ... }도 전부 같은 방식으로 동작한다.
핵심 통찰: 합성 가능성
Expression-based의 진짜 힘은 모든 게 합성 가능하다는 점이다. 값을 만드는 것끼리는 서로 끼워 넣을 수 있다.
let result = match status {
Status::Ok => if data.is_empty() { 0 } else { data.len() },
Status::Err => -1,
};
match 안에 if가 들어가고, 그게 다시 변수의 값이 된다. C였다면 임시 변수와 여러 줄의 statement로 풀어써야 하는 흐름을 하나의 식으로 표현할 수 있다.
C++ 비유로 말하자면, expression-based 언어는 모든 문법이 rvalue를 만든다. 그래서 어디든 끼워 넣을 수 있다.
스펙트럼으로 이해하기
흑백이 아니라 정도 차이다.
순수 statement-based ────────────────── 순수 expression-based
Pascal C/C++ Python Rust ML/Haskell Lisp
↑ ↑
제어구조 일부 expression 모든 것이 expression
(lambda, 삼항) (괄호 자체가 함수 호출)
- Lisp가 가장 극단적이다.
(+ 1 2)처럼 괄호 친 모든 게 expression이고, 언어 자체가 expression 트리다. - Haskell도 거의 순수 expression-based.
- Rust는 실용적인 expression-based. let 바인딩 같은 statement도 있지만, 제어 흐름은 모두 expression화했다.
- **C/C++**은 assignment(
=)나 comma operator(,) 같은 일부만 expression이고, 제어 구조는 statement.
왜 이게 중요한가
Expression-based 설계는 함수형 프로그래밍의 영향이다. "코드는 값을 변환하는 식의 조합이다"라는 시각이 깔려 있다. 이게 주는 장점은:
- 표현력: 임시 변수와 분기를 줄여 코드가 짧아진다
- 합성성: 작은 부품을 큰 부품으로 조립하기 쉽다
- 참조 투명성: expression은 그 값으로 치환 가능 — 추론과 최적화에 유리하다
- 불변성과 잘 맞음: 값을 만드는 식의 조합이라 mutation이 줄어든다
Rust는 시스템 언어인데도 이 철학을 받아들였다. 그래서 C++보다 함수형 스타일을 자연스럽게 쓸 수 있고, Option/Result 같은 타입과 match의 조합이 깔끔하게 동작한다.
이 철학이 문법 차원에서 어떻게 드러나는지는 statements-vs-expressions|Statements vs Expressions에서 더 구체적으로 볼 수 있다.
한 줄 요약
Expression-based 언어는 거의 모든 문법 요소가 값을 만들도록 설계되어, 식끼리의 합성을 통해 프로그램을 구성한다. Rust는 시스템 언어이면서도 이 철학을 받아들인 대표적인 사례다.