Zig에서 배운 교훈

발행: (2026년 2월 12일 오전 10:05 GMT+9)
24 분 소요

Source: Hacker News

번역할 텍스트를 제공해 주시면 한국어로 번역해 드리겠습니다.

Zig의 접근 방식

Zig 언어는 Andrew Kelley가 만들었으며, 표준 라이브러리 범위에 대해 의도적인 입장을 취합니다. 표준 라이브러리는 저수준의 기본 유틸리티에 초점을 맞춥니다: 메모리 할당자, 데이터 구조, 문자열 연산, 그리고 크로스‑플랫폼 OS 추상화. 도메인‑특화 기능은 명시적으로 제외됩니다.

커뮤니티 논의에서 이 입장이 명확히 정리되었습니다:

  • 인‑메모리 연산은 포함됩니다. 할당자, 큐, 문자열, 그리고 기본 데이터 구조는 사실상 모든 프로그램에 필요합니다.
  • 파일 포맷 처리는 포함되지 않습니다. Tar, zip, JPEG 등과 같은 포맷은 너무 특수화된 것으로 간주됩니다. 각각이 “그 자체로 거대한 프로젝트”이며 전용 라이브러리에서 다루는 것이 바람직합니다.
  • 고수준 프레임워크는 포함되지 않습니다. 예를 들어 HTTP 클라이언트는 범용 시스템 언어의 표준 라이브러리에는 부적절합니다.

Zig는 단순히 구성 요소를 추가하지 않을 뿐만 아니라, 적극적으로 제거하기도 합니다. std-lib-orphanage 저장소(2025년 11월 보관)는 MIT 라이선스로 표준 라이브러리에서 분리된 코드를 포함하고 있어, 커뮤니티가 유지보수할 수 있도록 합니다. 예시:

  • realpath()는 이식성이 없고, 레거시 권한 모델에 의존하며 “호출 자체가 버그가 되는 경우가 많다”는 이유로 제거되었습니다.
  • 레드‑블랙 트리 구현이 커뮤니티 소유로 이전되었습니다.
  • 파일 시스템 API가 std.fs에서 std.Io로 재구성되어, 적절한 범위를 더 잘 반영하도록 바뀌었습니다.

표준 라이브러리를 축소하려는 이러한 의지는 눈에 띕니다. 대부분의 언어 커뮤니티에서는 추가된 것이 영구적이지만, Zig는 표준 라이브러리를 “유지 보수 부담을 정당화하지 못하는 구성 요소가 있을 때는 축소해야 하는” 선별된 컬렉션으로 취급합니다.

Zig의 미니멀리즘이 실현 가능한 이유는 언어에 일류 패키지 매니저가 포함되어 있기 때문입니다. 서드파티 의존성을 손쉽게 가져올 수 있습니다. 표준 라이브러리에서 어떤 것이 사라지더라도 사용자는 좌초되지 않으며, 의존성을 추가하고 작업을 계속할 수 있습니다.

핵심적인 촉진 요소: 작은 표준 라이브러리는 대안에 쉽게 접근할 수 없을 경우 제약이 되지만, 패키지 매니저가 있으면 장점이 됩니다. 표준 라이브러리는 핵심에 집중하고, 나머지는 생태계가 흡수합니다.

C++ 표준화에서의 경제적 비대칭

C++ 표준화의 경제 구조는 근본적인 비대칭을 보여줍니다. 제안자는 몇 년에 걸쳐 한정된 노력을 투자합니다. 제안이 채택되면 그 비용은 종료됩니다. 그러나 표준은 영구적으로 그 추가를 고려해야 합니다:

  • 이후의 모든 제안은 새로운 구성 요소와의 상호 작용을 분석해야 합니다.
  • 모든 핵심 언어 진화(컨셉, 리플렉션, 계약)는 기존 라이브러리 영역에 미치는 영향을 고려해야 합니다.
  • 인접 영역에서 발생하는 모든 결함 보고는 잠재적으로 이를 연루시킬 수 있습니다.
  • 모든 컴파일러 벤더는 이를 영원히 구현하고 유지해야 합니다.
  • 모든 ABI 문제는 미래 진화를 영구적으로 제한합니다.
  • 모든 교육자는 이를 가르칠지 여부를 결정해야 합니다.
  • 모든 새로운 C++ 프로그래머는 이를 배우거나, 혹은 피하는 방법을 배워야 합니다.

표준의 조합적 복잡성은 단조롭게 증가하며, 이 복잡성 부담은 모든 미래 위원회 작업에 걸쳐 영원히 누적됩니다. 제안자는 한 번만 비용을 지불하고, 나머지는 모두가 부담합니다.

이 비대칭은 고전적인 경제 외부효과를 만들어냅니다. 제안자는 표준화(명성, 설계에 대한 정식 지위)라는 집중된 이익을 얻는 반면, 확산되고 영구적인 유지 비용은 원래 결정에 목소리를 내지 못한 대부분의 미래 위원회 참여자들에게 사회화됩니다.

합리적인 인센티브는 제안자가 장기 비용을 거의 부담하지 않으므로 공격적으로 제안을 하고 추가를 비판 없이 옹호하도록 만들게 됩니다. 제안자가 영구적인 비용을 내부화하도록 강제하는 메커니즘이 없으면, 표준 라이브러리는 한계 없이 성장하게 됩니다.

C++ 표준 라이브러리 교훈적인 사례

  • std::regex: 출시 당시 느렸으며, ABI 제약 때문에 수정이 불가능하고, 전문가들은 성능이 중요한 코드에서는 절대 사용하지 말라고 조언한다.
  • std::any: 아무도 필요로 하지 않았던 어휘형; 거의 사용되지 않으며, 타입 안전성을 희생하고, 표준화 후회 사례로 자주 언급된다.
  • std::auto_ptrstd::rel_ops: 결함 인식부터 제거까지 15년 이상 걸렸다.
  • std::codecvt facets: 폐기되었지만 여전히 유지되고 있다.
  • std::filesystem: 2003년에 고정된 인코딩 가정 때문에 Windows에서 문자 깨짐(모지베이크)이 발생한다; vcpkg는 “std::filesystem 사용을 완전히 제거했다”.

각 항목은 제안 당시에는 합리적으로 보였지만, 현재는 최소한의 이득에 비해 지속적인 비용을 초래한다. 위원회는 표준화된 기능이 약속한 가치를 제공했는지 감사할 공식적인 메커니즘이 부족하다.

제도적 쇠퇴

Samo Burja의 Great Founder Theory는 기능적 제도는 규칙이 아니라 예외라고 관찰한다. 제도는 시간이 지남에 따라, 그것들을 만든 살아있는 지식—특정 결정이 내려졌는지에 대한 이해—가 불완전한 전달을 통해 약해지면서 쇠퇴한다. 각 세대는 “복사본의 복사본”으로 작업하며, 생성 원칙이 없으면 전통은 잃어버린 것을 회복할 수 없다.

이 패턴은 C++ 표준 라이브러리에 직접 적용된다.

Source:

표준 라이브러리 설계에서의 지식 문제

설계 근거, 고려하고 거부한 트레이드‑오프, 그리고 특정 API 형태가 선택된 이유에 대한 이해—이러한 지식은 설계자들의 머릿속에 존재하며 그들이 물러나거나 사망하면 사라집니다.

Beman Dawesstd::filesystem을 설계하고 14년간 관리했습니다. 그가 2020년에 사망했을 때, 그 설계 뒤에 있던 살아있는 지식 전통도 함께 사라졌습니다. 이제 위원회는 사양 텍스트에서 의도를 역공학해야 합니다.

표준에 추가되는 모든 구성 요소는 보존해야 할 또 다른 지식 전통을 만들게 됩니다. 더 작은 표준 라이브러리는 다음을 의미합니다:

  • 유지해야 할 전통이 적음
  • 계승 위기가 적음
  • 미래 위원회 구성원이 탐색해야 할 누적 복잡성이 감소

GFT의 제도적 인센티브에 대한 관찰

GFT는 비기능적 제도에서 다음과 같은 패턴을 확인합니다: 제도의 몸체가 기능보다 외양을 최적화한다. WG21의 맥락에서 이는 기존 구성 요소를 유지·개선·제거하는 어려운 작업보다 구성 요소를 추가하는(가시적이고 측정 가능한 진전) 편향으로 나타납니다.

  • 위원회 구성원 중 std::codecvt를 제거함으로써 경력을 쌓는 사람은 없습니다.
  • 경력은 추가하는 제안으로 구축됩니다.

이러한 비대칭적 인센티브는 확장이 사용자에게 도움이 되든 그렇지 않든 확장을 지속시킵니다.

Zig의 대조적 접근 방식

Zig가 표준 라이브러리에서 구성 요소를 제거하는 데 적극적인 자세를 보이는 것은 근본적으로 다른 제도적 입장을 보여줍니다: 수축을 정당한 진보로 간주한다는 것이죠. 이는 GFT가 말하는 “라이브 플레이어”—관료적 절차가 저항하는 결정을 내릴 권한과 비전을 가진 사람—을 필요로 합니다.

Zig의 포함 기준은 암시적이지만 명확합니다:

구성 요소는 오직 거의 모든 프로그램이 필요로 하는 저수준, 기본 기능을 제공할 때만 표준 라이브러리에 포함됩니다.

C++는 이 기준을 명시적으로 해야 합니다.

Source:

라이브러리 컴포넌트를 표준화해야 하는 시점은 언제인가?

컴포넌트는 다음 두 조건을 모두 만족할 때만 표준화해야 합니다:

  1. 안정성 확신

    • 설계가 수년간의 실제 사용을 통해 수렴되었다.
    • 중요한 인터페이스 변경이 요구되지 않았다.
    • 알려진 결함이 해결되었으며, 미뤄두지 않았다.
  2. 용어 필요성

    • 독립적인 라이브러리 생태계가 상호 운용을 위해 타입 일치를 명백히 요구한다.
    • 표준화가 해결할 수 있는 조정 실패 사례가 존재한다.
    • 제3자 배포만으로는 이러한 실패를 해결할 수 없다.

“이것은 유용할 것이다”는 필요조건이지만 충분조건은 아니다. 유용한 라이브러리는 표준 외부에서도 충분히 성장할 수 있다. 핵심 질문은 왜 그 유용성이 표준화가 아니라 제3자 배포를 통해 해결되지 못하는가 입니다.

Zig의 철학은 패키지 매니저가 외부 라이브러리를 일등 시민으로 만든 덕분에 작동합니다. C++는 이를 갖추지 못했으며, 그 결과 모든 것을 표준에 넣어야 한다는 압력이 생깁니다. 답은 그 압력에 굴복하는 것이 아니라 생태계에 투자하는 것입니다.

라이브러리 확장의 기회비용

위원회의 대역폭은 한정적이며 소중합니다. 틈새 라이브러리 구성 요소에 회의 시간을 할애할 때마다, 아님 다음과 같은 일에 할당되지 않은 시간입니다:

  • 모두에게 혜택을 주는 핵심 언어 개선
  • 실제 조정 실패를 해결하는 어휘 타입
  • 외부 라이브러리를 더 쉽게 접근할 수 있게 하는 생태계 인프라

라이브러리 확장의 기회비용은 오직 위원회만 할 수 있는 작업의 진행 지연으로 지불됩니다. 외부 라이브러리는 누구든 유지할 수 있지만, 언어 진화와 어휘 조정은 위원회가 필요합니다.

C++에서의 래칫 효과

C++ 표준은 역사적으로 제거를 거의 불가능하게 취급해 왔습니다:

  • 폐기는 10년이 걸립니다.
  • 실제 제거는 그보다 더 오래 걸립니다.

이 일방향 래칫은 무한한 성장을 보장합니다.

Zig는 대안을 제시합니다: 어떤 구성 요소가 더 이상 그 자리를 정당화하지 못하면 이동시키는 것입니다. 코드는 사라지지 않고, 핵심에 비용을 부과하지 않으면서 진화할 수 있는 다른 위치로 옮겨집니다.

C++는 ABI 안정성 및 수십 년에 걸친 배포 코드 때문에 Zig의 접근 방식을 정확히 복제할 수 없습니다. 하지만 위원회는 마인드셋을 채택할 수 있습니다:

  • 추가는 영구적인 것이 아니라 임시라고 가정해야 합니다.
  • 모든 구성 요소는 주기적으로 지속적인 포함을 정당화해야 합니다.
  • 고정할 수 없는 알려진 결함이 있는 시설은, 이를 정직하게 인정하는 것이 사용자에게 사전 가장을 유지하는 것보다 더 도움이 됩니다.

순환 논증

  • 표준 라이브러리는 생태계에 좋은 의존성 관리가 부족하기 때문에 성장한다.
  • 모든 중요한 것이 표준에 포함될 것으로 기대되기 때문에 생태계가 정체된다.

이 순환을 깨려면 방향을 선택해야 한다. Zig는 생태계 투자를 선택했다. C++도 같은 방식을 고려해야 한다.

지속적인 확장의 결과

  • 표준은 ABI‑고정 설계들의 저장소가 되며, 이는 표준화된 시대의 가정을 반영합니다.
  • 성능에 민감한 조직들은 내부 대안으로 std:: 사용을 포기합니다.
  • 표준 라이브러리는 본래 의도와는 달리 API 경계에서만 사용되고 내부에서는 회피되는 형태가 됩니다.

표준은 명세를 제공할 뿐, 품질을 보장하지는 않습니다:

  • std::regex는 명세되어 있지만 느립니다.
  • std::filesystem은 명세되어 있지만 인코딩 버그가 있습니다.

명세는 인터페이스의 이식성을 보장하지만 구현의 정확성이나 목적 적합성을 보장하지 않습니다.

외부 라이브러리는 자체적인 보장을 제공할 수 있습니다:

  • 테스트 스위트
  • 벤치마크
  • 배포 증거
  • 신속한 유지보수

이러한 요소들은 ISO 문서 번호보다 사용자에게 더 의미가 있는 경우가 많습니다.

교육적 함의

초보자는 일관된 표준 라이브러리에서 라이브러리보다 더 큰 혜택을 얻습니다.

  • 잘 작동하는 작은 라이브러리는 가르치기 더 쉽습니다.
  • 함정이 많은 큰 라이브러리는 탐색하려면 전문가 수준의 지식이 필요합니다.

std::regex는 사용하되 성능을 위해서는 사용하지 말라”와 “std::filesystem을 사용할 때 Windows의 인코딩에 주의하라”와 같은 문구는 초보자에게 친절한 가르침이 아닙니다.

결론

Zig 프로그래밍 언어는 작고 집중된 표준 라이브러리가 제한이 아니라 강점임을 보여줍니다—외부 라이브러리를 쉽게 이용할 수 있게 하는 생태계 인프라와 결합될 때 말이죠.

C++은 다른 구조적 현실에 직면해 있습니다:

  • 통합된 패키지 매니저가 없음
  • ABI 안정성 제약
  • 수십 년에 걸친 배포 코드

그럼에도 불구하고 Zig의 임시 포함, 주기적 정당화, 그리고 생태계 투자라는 사고방식을 채택하면 무제한적인 성장 억제와 표준 라이브러리를 부담스러운 레거시가 아닌 유용하고 교육 가능한 기반으로 유지할 수 있습니다.

이러한 제약은 현실입니다. 하지만 이는 근본적인 경제성을 바꾸지는 못합니다. 표준 라이브러리에 추가되는 모든 항목은 영구적인 의무를 생성합니다. 모든 의무는 제한된 위원회 자원을 소모합니다. 후회되는 추가 항목을 유지보수하는 데 소비된 한 시간은 전체 C++ 커뮤니티에 도움이 될 작업에 할당되지 않은 시간입니다.

위원회의 가장 귀중한 자원은 구성원들의 집단적인 전문 지식과 주의력입니다. 영구적인 의무를 받아들이기 전에 엄격한 증거를 요구하는 철학은 표준 라이브러리를 확장하여 생태계 인프라의 부재를 폭넓음으로 보완하려는 접근보다 C++ 커뮤니티에 더 큰 도움이 됩니다.

Zig는 묻습니다: “이것이 표준 라이브러리에 포함되어야 하는가, 아니면 생태계가 처리할 수 있는가?”
C++도 모든 라이브러리 제안에 대해 동일한 엄격함으로 같은 질문을 해야 합니다.

  • Kelley, Andrew. Zig 프로그래밍 언어 소개
  • Zig std‑lib‑orphanage. 2025년 11월 보관됨.
  • Ziggit: 표준 라이브러리를 “배터리 포함”으로 해야 할까?. 2024.
  • Burja, Samo. 위대한 창업자 이론. 2020.
  • Muller, Jonathan; Laine, Zach; Lelbach, Bryce Adelstein; Sankel, David. [P3001R0] “std::hive 및 유사 컨테이너는 표준 라이브러리에 적합하지 않다.” 2023년 10월.
  • Winters, Titus. [P2028R0] “ABI란 무엇이며, WG21은 이에 대해 무엇을 해야 하는가?” 2020.
  • Winters, Titus. [P1863R0] “ABI – 지금 아니면 영원히.” 2019.
  • Dos Reis, Gabriel. [P0939R4] “ISO C++를 위한 방향.”
  • Jabot, Corentin. “당신의 체리를 위한 케이크: C++ 표준 라이브러리에 무엇이 들어가야 할까?”
  • Winters, Titus. “C++ 표준 라이브러리에 무엇이 들어가야 하는가.” Abseil Blog.
  • R0 (2026‑02‑06): Zig 표준 라이브러리 철학과 이를 WG21에 적용 가능성을 검토하는 초기 초안.
0 조회
Back to Blog

관련 글

더 보기 »

Zig vs Go: 제네릭

소개 Go는 버전 1.18에서 generics를 도입하여 함수와 struct를 타입으로 매개변수화할 수 있게 했습니다. Zig는 오랫동안 compile‑time generics를 지원해 왔습니다.

PQP 언어

개요 이름: PQP Language 설명: 언어를 구축하는 과정이 어떻게 작동하는지를 보여주기 위해 만든 미니 프로그래밍 언어입니다. !pichttps://med...

특수 문자 | C++ 초보

String와 특수 문자 Escape 문자는 문자열이나 텍스트 안에서 특수 명령·문자를 쓰기 위해 사용됩니다. ' ' – 따옴표 안에 따옴표를 ...