프로그래밍 언어별 열거형 티어 정리
Ranking Enums in Programming Languages by Premature Abstraction
프로그래밍 언어별 열거형(Enum) 구현 방식 및 티어 비교
이 영상은 단순히 상수를 그룹화하는 기능을 넘어, 각 프로그래밍 언어가 열거형을 어떻게 설계하고 구현했는지에 따라 코드의 안전성과 표현력이 어떻게 달라지는지 상세히 분석하고 등급(Tier)을 매겨 정리한 자료입니다.
1. 열거형의 정의와 기본 개념
- 프로그래밍 언어에서 열거형은 흔히 상수를 편리하게 관리하거나 범위를 제한하여 그룹화하는 수단으로 소개됩니다.
- 그러나 언어의 설계 철학에 따라 열거형은 단순한 상수의 집합을 넘어 타입 시스템의 핵심적인 역할을 수행하기도 합니다.
2. D 티어: 기본적인 지원이 부족하거나 우회하는 언어
- 자바스크립트(JavaScript)
- 예약어의 부재:
enum이 예약어이긴 하지만 실제 기능은 존재하지 않습니다. - 구현 방식: 일반적인 객체(Object) 를 사용하여 열거형을 흉내 냅니다.
- 주요 단점:
- 값의 유일성(Uniqueness) 이 보장되지 않아 버그가 발생할 수 있습니다.
- 객체를 동결(Freeze) 하지 않으면 나중에 값을 실수로 변경할 위험이 있습니다.
- 서로 다른 열거형의 값을 비교하는 것을 막을 수 없습니다.
- 심볼(Symbol) 을 사용하여 유일성 문제를 해결할 수 있으나, 사용 시 다른 불편함이 따릅니다.
- 컴파일러나 인터프리터가 모든 사례를 처리했는지 확인하는 전수 검사(Exhaustiveness Check) 기능이 없어 확장 시 위험합니다.
- 예약어의 부재:
- 고(Go)
- 기본 기능 부재: 네이티브 열거형 문법이 없어 일반적으로 상수(Constants) 를 정의하여 사용합니다.
- 구현 방식:
IOTA키워드를 사용하여 자동으로 번호를 부여하며, 타입 별칭을 통해 서로 다른 열거형 간의 비교를 최소한으로 방지합니다. - 장점: 비트 마스크를 정의할 때 문법적으로 다소 우아한 표현이 가능합니다.
- 주요 단점:
- 열거형 문법 중 가장 혼란스러운 문법을 가졌다는 평가를 받습니다.
- 컴파일러가 모든 열거형 변수를 처리했는지 강제하지 않습니다.
- 상수의 스코프(Scope)가 구분되지 않음: 다른 열거형 간에 이름 충돌이 발생할 수 있는 가장 큰 문제를 안고 있습니다.
3. C 티어: 편의 기능은 있으나 구조적 한계가 있는 언어
- 파이썬(Python)
- 구현 방식: 별도의 전용 문법은 없으나 표준 라이브러리의
Enum베이스 클래스를 상속받아 기능을 모방합니다. - 기능적 특징: * 단순 값 비교 문제를 해결하여 다른 열거형의 동일한 값과 비교 시 거짓(False)을 반환합니다.
- 문자열처럼 동작하게 하려면
StrEnum을, 정수처럼 동작하게 하려면IntEnum을 사용할 수 있습니다. auto()기능을 통해 변수 이름을 소문자 값으로 자동 할당하는 편의를 제공합니다.
- 문자열처럼 동작하게 하려면
- 주요 단점:
- 서로 다른 열거형의 값이 참(True)으로 비교되는 것을 막으려면 타입 체커를 별도로 사용해야 합니다.
unique데코레이터를 추가해야만 값의 중복을 강제로 막을 수 있습니다.match문을 사용할 수 있지만, 인터프리터 수준에서 모든 사례를 처리했는지 검사하지 않습니다.
- 구현 방식: 별도의 전용 문법은 없으나 표준 라이브러리의
- 타입스크립트(TypeScript)
- 구현 방식: 자바스크립트의 예약어를 활용하여 실제
enum문법을 제공합니다. - 기능적 특징: * 0부터 시작하는 자동 번호 부여 기능을 제공하며, 문자열이나 혼합 타입을 사용할 수 있습니다.
- 컴파일러가 동일한 타입 내에서의 비교만 허용하도록 보장합니다.
- 주요 단점:
- 논란의 여지가 있는 내부 구현: 컴파일 시 키와 값의 양방향 매핑 객체를 생성하는데, 이는 문자열 열거형에서는 동작이 달라지는 등 일관성이 부족합니다.
- 많은 개발자가
as const를 사용한 일반 객체나 문자열 유니온(String Unions) 을 대안으로 선호합니다. - 기본적으로 전수 검사 기능이 없으며,
never타입을 활용한 편법이나 별도의 도구(ESLint)를 사용해야만 강제할 수 있습니다.
- 구현 방식: 자바스크립트의 예약어를 활용하여 실제
** 4. B 티어 및 A 티어: 타입 안전성과 객체 지향적 접근**
- C++
- 전통적 방식의 한계: 과거의 열거형은 단순히 정수(Integer)에 불과하여 타입 안전성이 없었고, 이름 충돌 문제(스코프 미지원)가 있었습니다.
- 개선(B 티어): C++ 11에서 도입된 열거형 클래스(Enum Class) 를 통해 이러한 문제들을 완화했습니다.
switch문에서 모든 값을 처리하지 않으면 경고를 줄 수 있지만, 이는 선택 사항(Opt-in)이며 여전히 기능적 확장이 부족합니다.
- 자바(Java)
- B 티어(이전 버전): 과거 버전은 기능이 제한적이었습니다.
- A 티어(Java 17 이상): 열거형이 완전한 객체(Object) 로 취급됩니다.
- 데이터와 메서드를 직접 부착할 수 있어 매우 강력합니다.
- Java 17의
switch식(Expression)을 통해 컴파일러 수준의 전수 검사가 가능해졌습니다. - 봉인된 클래스(Sealed Classes) 의 도입으로 대수적 데이터 타입을 모방할 수 있게 되었습니다.
- 코틀린(Kotlin) - A 티어
- 현대적인 자바와 유사한 기능을 제공하지만 훨씬 더 깔끔한 접근 방식을 취합니다.
when식을 통한 강력한 전수 검사를 지원하며, 상황에 따라 열거형 클래스나 봉인된 클래스를 선택하여 모델링할 수 있는 유연성을 제공합니다.
5. S 티어: 대수적 데이터 타입을 지원하는 완성형 열거형
- 러스트(Rust)
- 핵심 철학: 열거형이 타입 시스템의 핵심이며, 대수적 데이터 타입(Algebraic Data Types) 을 완벽하게 구현합니다.
- 모델링의 강력함: "불가능한 상태를 표현할 수 없게 만드는(Making illegal states unrepresentable)" 도메인 모델링이 가능합니다.
- 예: '죽은 플레이어' 상태에서는 '체력' 값이 존재할 수 없도록 구조적으로 정의할 수 있습니다.
- 표준 라이브러리 활용: * Null의 부재: 대신
Option열거형(Some또는None)을 사용합니다.- 예외 처리의 부재: 대신
Result열거형(Ok또는Err)을 사용합니다.
- 예외 처리의 부재: 대신
- 안전성: 컴파일러가 모든 가능한 변형을 처리하도록 강제하므로 런타임 오류를 획기적으로 줄입니다.
- 스위프트(Swift)
- 러스트와 대등한 수준의 열거형 시스템을 갖추고 있습니다.
- 일반적인 열거형 기능에 데이터를 부착하는 기능은 물론, 필요에 따라 원시 값(Raw Values) 을 가질 수도 있는 유연함을 보입니다.
- 컴파일러 수준의 철저한 전수 검사를 지원하여 안정성을 보장합니다.
6. 결론
- 열거형은 단순한 상수의 나열처럼 보일 수 있으나, 언어 설계에 따라 도메인을 표현하는 방식과 코드의 안전성에 막대한 차이를 만듭니다.
- 고(Go)의 단순한 상수 방식부터 러스트(Rust)나 스위프트(Swift)의 정교한 대수적 데이터 타입까지, 각 언어의 열거형 구현 방식은 그 언어가 지향하는 철학을 극명하게 보여줍니다.
토픽:
프로그래밍