불변과 상수, 혼용되는 표현 깨부수기

RanolP·2023년 2월 2일
1

맥락을 단순하게 만들어 관리하는 것은 복잡성을 줄이고, 잘 동작하는 코드를 만들기에 좋은 접근 방식입니다. 우리는 그 방법 중 하나로 불변Immutable 값/상수Constant 값을 주로 활용하곤 합니다. 하지만 불변 값은 대체 뭐가 변하지 않는다고 보장하는 걸까요? 이 글에서는 불변/상수라는 용어로 혼동되는 여러 개념을 명확히 구분지어 이름을 붙여보고자 합니다.

불변 쪼개기

재대입 금지No Reassignment/읽기 전용Readonly/불변 변수Immutable Variable

다양한 언어들이 불변 변수[1](다른 말로는, 읽기 전용 변수)를 만드는 기능을 제공합니다. 다음은 여러 언어로 작성한 불변 변수의 예시입니다.

// Java
final int a = 1;
// Kotlin
val a = 1
// C#
readonly int a = 1;
// JavaScript
const a = 1;

이러한 불변 변수는 변수의 이름에 새로운 값을 넣을 수 없는, 다시 말해 재대입이 불가능하다는 성질을 띕니다. 여기서 말하는 불변성은 이름과 값 사이 관계의 불변성만 말하고, 값 자체의 불변성과는 무관하다는 것입니다. 따라서 값의 불변성과 혼동을 불러일으키는 불변 변수 및 읽기 전용이라는 이름 대신 재대입 금지 등의 용어를 고려해보아야 합니다.

동결Frozen/불변 콜렉션Immutable Collection

언어 표준 라이브러리 및 기타 라이브러리 등에서 동결 집합Frozen Set이나 불변 맵Immutable Map 등을 본 적이 있을 것입니다. 이러한 자료 구조들은 자료 구조 그 자체에 원소를 추가, 교체, 제거하는 등의 연산을 막지만, 각 원소 내부의 상태를 불변으로 만들어주지는 않습니다. 또, 동결 콜렉션이라고 해서 불변 상태만으로 구현해야 하는 것도 아닙니다. 예를 들어서, 목록의 원소들은 동결된 상태지만, 최적화 목적으로 목록의 어느 값이 자주 읽히는지 필드에 기록하는 특수 목적의 동결 목록을 만들 수도 있습니다. 따라서, 불변 콜렉션 등의 용어 대신 (다행스럽게도 널리 쓰이는) 동결 콜렉션이라는 용어를 사용해야 합니다.

불변 값Immutable Value/불변 객체Immutable Object

드디어 우리가 흔히 '불변'이라 하면 떠올리는 개념까지 왔습니다. 보통 불변 값이나 불변 객체는 (자기 자신뿐만 아니라 하위 속성들에도 재귀적으로) 변경되지 않는다는 조건을 붙인 값으로, 상당히 강한 제약 조건 덕분에 외부에서 값을 수정할 걱정을 덜고, 캐싱을 통해 값을 재활용하기 용이하며, 스레드 경계 너머로도 마음껏 값을 공유할 수도 있는 등 수많은 장점을 갖고 있습니다. 불변 값이든 객체든, 변수의 이름이 아닌, 값/객체의 성질임을 명확히 쓸 수 있는 불변 값, 그리고 불변 객체 모두 명확한 표현입니다. 불변 변수라고 쓰는 오류를 범하지 않도록 합시다.

상수 쪼개기

재대입 금지No Reassignment/상수Constant

JavaScript 등의 언어에서는 const 키워드를 통해 재대입 금지 변수를 초기화할 수 있게 하여 혼란을 불러옵니다. 이런 경우에는 앞서 언급했듯, 재대입 금지 등의 용어를 고려하는 편이 낫습니다.

컴파일 시 평가Compile-time Evaluation/상수 평가Constant Evaluation/정적 값 상수Static Valued Constant

때떄로, 저희는 상수를 정의하기 위해 수식 따위를 필요로 하곤 합니다. 가령, τ(타우)의 절반을 π(파이)로 정의한다거나 하는 등 말입니다. 이런 값들은 실행 중에 평가될 필요가 없으며, 상수 접기Constant Folding 등의 최적화 기술을 통해 컴파일 시점에 평가할 수 있습니다. 나아가, C++ 등의 언어에서는 constexpr, consteval, constinit 등의 키워드를 활용하면 값이 컴파일 시점에 평가되도록 만들 수 있습니다.

이러한 기능이 주로 상수에 쓰이고, 예약어 이름에 const가 포함되어 상수가 무조건 갖는 성질로 오해하는 경우가 있을 수 있습니다. 하지만, 이 속성은 재대입 금지, 불변 등과 별개의 요소입니다. 이 속성만을 일컬을 때에는 컴파일 시 평가와 같은 용어를 사용하는 편이 좋겠습니다.

tl; dr

이 글에서는 다음과 같이 용어를 구분하기를 권하고 있습니다.

상황기존 용어제안 용어
변수가 재대입되지 않는다(이름 - 값 관계가 불변)읽기 전용 변수, 불변 변수, const 변수재대입 금지 변수
콜렉션에 원소가 추가/교체/삭제되지 않는다(콜렉션 원소 저장고가 불변)동결 콜렉션, 불변 콜렉션동결 콜렉션
값 자체가 변하지 않는다(값 자체가 불변)불변 값, 불변 객체불변 값, 불변 객체
값이 컴파일 시점에 평가된다컴파일 시 평가/상수 평가/정적 값 상수컴파일 시 평가

각주

↩️ [1] 불변 변수라는 말은 꽤나 모순적으로 보이는 용어입니다. 컴퓨터 공학에서 수학 용어 Variable의 번역어인 변수를 그대로 사용하지만 그 개념은 어떤 '이름'에 '값'이 묶인 것을 말하므로 사뭇 다름을 알 수 있습니다. 따라서, 이 정의를 생각해볼 때, 불변 변수는 이름에 새로 값을 묶을 수 없는 것을 의미한다고 볼 수 있습니다.

참고 자료

- Wikipedia, "Immutable object"
- Wikipedia, "Constant (computer programming)"

profile
사람과 컴퓨터 사이를 이어주는 소프트웨어를 만듭니다

0개의 댓글