FEInterview Prep

Velog

자바스크립트에서 Records & Tuples 제안이 철회된 이유

Records & Tuples 는 "불변 + 깊은 비교" 라는 매력적인 신원시 타입이었지만, 신원시 타입 추가의 엔진 비용 + `===` 의미 일관성 + 깊은 비교의 성능 세 벽에 부딪혀 철회됐다. 대안은 Composite.

2025-07-03·6분 읽기
JavaScript
원문 보기 ↗

핵심 요약

R&T 제안의 골자:

const t1 = #[1, 2, 3];
const r1 = #{ a: 1, b: t1 };
t1 === #[1,2,3];      // true (구조적)
r1 === #{ a:1, b: #[1,2,3] }; // true
Map 의 키로도 사용 가능

매력 포인트:

  • 구조적 동등성 — useMemo/useEffect deps, 캐시 키, 상태 비교가 단순
  • 깊은 불변 — 의도치 않은 변형 방지

철회된 3가지 벽:

본질영향
신원시 타입 추가엔진 모든 형변환·hot path 에 분기 추가R&T 안 쓰는 코드도 느려짐
=== 의미 변경4번째 동등성(SameValueNonNumeric 등) 깨짐 또는 5번째 추가JS 멘탈 모델 부담
깊은 비교 성능인터닝 없이 선형 시간 — 최적화 보장 어려움구현자들 commit 회피

대안: Composite객체 기반(원시 타입 아님) + Composite.equal(a, b) 명시 비교 + Map/Set 은 구조 비교, WeakMap/WeakSet 은 참조 비교(불일치 존재).

이 글의 핵심 교훈은 "언어에 새 원시 타입 을 더하는 비용은 보이는 것보다 훨씬 크다" 다. R&T 는 "#{} / #[] 만 추가하면 끝" 처럼 보이지만, JS 엔진에는 모든 타입 검사·형변환 경로 에 분기를 추가해야 하고, === 동등성의 의미 까지 흔든다. 그래서 "좋은 아이디어" 와 "표준에 들어갈 수 있는 아이디어" 사이에는 언어 코어 영향 이라는 별개 축이 있다.

R&T 가 무엇이었는지보다, 왜 철회되었는지 가 면접에서 더 가치 있다. 다음 세 가지를 자기 언어로 설명할 수 있어야 한다.

  • 새 원시 타입이 엔진에 끼치는 전역적 비용 (R&T 안 쓰는 코드도 영향)
  • 깊은 비교가 상수 시간 보장 이 안 되어 === 를 "가벼운 연산" 이라는 가정에 도전
  • 동등성 비교 종류가 4 → 5로 늘어나는 멘탈 부담

그리고 대안인 Composite(객체 기반 + 명시적 비교)이 어떤 다른 트레이드오프를 채택하는지 함께 답할 수 있으면 좋다.

학습 포인트

면접 답변으로 연결할 학습 포인트입니다.

원시 타입 추가는 *언어 전체* 비용

JS 엔진은 모든 연산에서 피연산자 타입 을 확인한다(특히 동적 디스패치). 새 원시 타입이 들어오면 다음이 모두 영향받는다.

  • typeof, instanceof, ===, ==
  • 형변환 (+, ==)
  • inline cache / hidden class
  • 가비지 컬렉션 모델

결과적으로 R&T 를 안 쓰는 코드의 hot path 도 약간씩 느려진다. 이게 V8/JSC 구현자들이 "들이지 말자" 로 기운 결정적 이유 중 하나.

primitive typeinline cachehidden classtype tag
자주 하는 오해

"안 쓰면 비용 0" 이라고 보는 것. 엔진 차원의 분기/검사가 늘어 전역 약간씩 느려진다.

깊은 비교는 "가벼운 연산" 가정과 충돌

JS 의 ===상수 시간 가정 위에서 모든 표준 라이브러리·엔진 최적화가 쌓여 있다. R&T 는 깊이 N 의 구조에서 O(N) 비교가 필요하고, 인터닝(intern) 없이 빠르게 하기 어렵다.

const a = #[ /* 1만 항목 */ ];
const b = #[ /* 1만 항목 */ ];
a === b; // 구조 비교 — 1만 회 검사

R&T 가 들어가면 === 가 "비싼 연산" 가능성이 생기고, 이는 루프 안에서 안전하게 === 를 쓴다 는 모든 코드의 가정을 흔든다.

interningstructural equalityconstant timehash precompute
자주 하는 오해

"해시 미리 계산하면 되지 않나?" — 해시는 불일치 빠른 거부 만 도와주고, 일치 시엔 결국 깊이 비교가 필요하다.

동등성 종류의 폭증과 `Composite` 대안

JS 는 이미 4가지 비교가 있다.

  • ==(추상 동등)
  • ===(엄격 동등)
  • SameValue(Object.is)
  • SameValueZero(Map/Set/Array.includes)

R&T 는 이를 유지하든 깨든 부담이다. 유지하면 R&T 를 위한 5번째 종류 추가, 깨면 기존 코드 회귀. 이 모순을 비껴가려는 대안이 Composite:

  • Composite({ ... }) 로 객체 생성 (원시 아님)
  • === 는 여전히 참조 비교 — 기존 의미 보존
  • Composite.equal(a, b)명시 비교
  • Map/Set 은 구조 비교, WeakMap/WeakSet 은 참조 비교 — 불일치는 단점
SameValueSameValueZeroComposite proposalstructural key
자주 하는 오해

"Composite 가 R&T 의 완전 대체" 라는 인식. 사실 구조적 키 를 명시 메서드로 제한해 트레이드오프를 다른 방향으로 가져간다.

읽는 순서

  1. 1이론

    JS 의 4가지 동등성(==, ===, SameValue, SameValueZero)을 표로 정리하고, R&T 가 추가되었을 때 어떤 칸이 비는지 채워본다.

  2. 2구현

    polyfill 인 @bloomberg/record-tuple-polyfill 로 R&T 를 흉내 내 깊은 객체를 키로 쓰는 캐시를 만들어본다. 동일 구조를 1만 번 비교했을 때의 시간을 측정.

  3. 3실무

    프로젝트의 useMemo deps/캐시 키로 객체를 쓰는 곳을 골라, 직렬화 키 / immutable.js 인터닝 / Composite 제안 흉내 셋 중 어느 쪽이 더 적합한지 평가.

  4. 4설명

    동료에게 "왜 좋아 보이는 R&T 가 표준에 못 들어갔는지" 를 5분 안에 엔진 비용 / 동등성 / 깊은 비교 성능 세 축으로 설명한다.

면접 연결 질문

mediumRecords & Tuples 가 무엇이었고, 왜 철회되었는지 한 단락 안에 설명해주세요.
힌트

[감점 답변] "불변이라서 어려웠음". [좋은 답변] 불변 + 구조적 동등성 을 가진 두 신원시 타입(#{}/#[]). 매력은 분명했지만 (1) 신원시 타입이 엔진 hot path 전반에 비용, (2) === 의 "가벼운 연산" 가정과 충돌, (3) 동등성 종류가 4→5 로 폭증 — 이 셋이 표준 위원회/구현자 합의를 막아 철회됐다.

hardR&T 없이 "객체를 키로 쓰되 구조 비교" 가 필요할 때 현실적인 대안은 무엇인가요?
힌트

[감점 답변] "JSON.stringify 로 키 만들기". [좋은 답변] (1) 정규화된 직렬화 키 — 키 순서가 일관되도록 canonical-json 같은 라이브러리 사용 + Map<string, V>. 단 깊은 객체에 비용. (2) 인터닝 라이브러리immer/immutable-js로 동일 구조에 동일 참조 부여 → === 활용. (3) Composite 제안 — 표준화되면 1차 후보. 각 대안의 생성 비용 vs 비교 비용 vs 직관성 트레이드오프로 답하면 시니어 답.

hard신원시 타입을 추가하는 게 왜 "신클래스 추가" 와 본질적으로 다른가요?
힌트

[감점 답변] "새 키워드라서". [좋은 답변] 클래스는 오브젝트 한 종류 라 엔진 입장에선 기존 객체 경로만 따른다. 반면 원시 타입은 (1) typeof, instanceof, ===, == 등 전역 연산, (2) 형변환 규칙, (3) inline cache/hidden class 모델 까지 분기를 추가해야 한다. 결과적으로 R&T 안 쓰는 코드도 비용을 부담 한다 — 이게 결정적 차이.

자기 점검

R&T 가 도입됐을 때 `===` 의 의미가 어떻게 모호해질 수 있는지 예시를 들어 설명해보세요.
SameValueSameValueZero구조 비교참조 비교
자주 하는 오해

"=== 는 항상 참조 비교" 라는 단정. R&T 가 들어오면 일부 값에서는 구조 비교 로 동작해 의미가 분기된다.

`Composite` 제안이 R&T 와 같은 매력을 일부만 채우면서 표준화 가능성이 더 높은 이유를 말해보세요.
객체 기반명시 비교신원시 타입 회피
자주 하는 오해

"Composite 가 항상 더 좋다" 는 인식. 트레이드오프가 다를 뿐 R&T 의 문법적 매력 은 잃는다.