Zig의 comptime이 하지 않는 일들

6 hours ago 1

  • Zig의 comptime 기능은 매우 강력한 컴파일 타임 평가 기능을 제공하지만 의도적으로 제한적
  • 컴파일 타임 코드 실행 시 호스트 정보에 접근 불가능, 크로스 컴파일에 적합한 설계임
  • 동적 코드 생성, DSL, RTTI, I/O 등은 지원하지 않음, 대신 명시적인 타입 기반 코드 특수화 사용
  • RTTI는 직접 구현 가능, 단 컴파일 타임에만 존재하는 타입 정보를 런타임에 사용할 수 있게 재구성 가능함
  • comptime으로 새 타입 생성 가능하지만 API 확장은 불가, 사용자 정의 메서드 추가는 불가능함

Zig의 comptime이 하지 않는 일들

  • Zig의 comptime은 제네릭, 조건부 컴파일, 직렬화, ORM 등 강력한 기능을 제공함에도 불구하고 일부 기능은 명시적으로 제한됨
  • 그 제한들이 오히려 Zig의 설계를 간결하고 예측 가능하게 만듦
  • 호스트 정보 접근 불가 (No Host Leakage)

    • comptime 코드는 코드가 실행되는 시스템이 아닌, 타겟 플랫폼을 기준으로 동작
    • Zig에서는 컴파일 타임에 호스트 시스템의 엔디안, 포인터 크기 등 정보를 사용할 수 없음
    • 이는 크로스 컴파일을 고려한 안전성 확보 목적
    • 예시 코드에서 BF16 형식 숫자의 바이트 출력이 타겟 플랫폼에 따라 다름
  • 문자열 기반 코드 생성 없음 (No #eval)

    • Zig은 C의 #include, D 언어의 mixin, Rust 매크로처럼 동적으로 코드를 생성하는 기능을 제공하지 않음
    • 대신 comptime 인자 기반의 부분 평가(partial evaluation) 지원
    • 특정 인자가 컴파일 타임에 알려져 있으면, 해당 분기만 살아남아 코드 최적화 가능
  • DSL 문법 확장 불가 (No DSLs)

    • Zig에서는 Lisp, Rust처럼 사용자 정의 구문(syntax)을 만드는 기능이 없음
    • 모든 데이터는 Zig 문법에 따른 값(value) 형태로만 전달됨
    • 포맷 문자열(printf)처럼 제한된 DSL은 comptime 문자열로만 구현 가능
  • 런타임 타입 정보 없음 (No RTTI)

    • Zig은 Python 같은 동적 언어처럼 동작할 수 있지만, 타입 정보는 오직 comptime에만 존재
    • 런타임에서도 동작하도록 하려면 직접 RTTI 구조체를 정의하고, 포인터로 조작해야 함
    • 예: struct 필드의 이름과 오프셋 정보를 담은 RTTI 구조체 정의 후, 포인터로 필드에 접근
  • 새 API 생성 불가 (No New API)

    • Zig에서는 comptime으로 새 타입을 만들 수는 있지만, 이 타입에 메서드를 추가할 수 없음
    • Rust의 derive macro처럼 API를 확장할 수 없음
    • JSON 직렬화 구현 시 .to_json() 메서드를 추가할 수 없고, 전역 함수에 타입 인자를 넘기는 방식으로 구현
  • 컴파일 타임 IO 없음 (No IO)

    • Zig의 comptime은 파일 시스템, 네트워크, 데이터베이스 등 외부 리소스 접근을 금지
    • 이로 인해 재현 가능성, 안전성, 캐시 활용성이 높아짐
    • IO가 필요하면 build 시스템인 build.zig을 사용하여 사전 생성된 Zig 코드 import 방식 사용
  • 정리: El Disco (추상화와 단순성의 균형)

    • Zig은 강력한 메타프로그래밍 기능을 제공하면서도, 매우 제한적인 설계를 통해 예측 가능성을 확보
    • 이 제한 덕분에 Zig의 comptime은 실용적이며, 이해하기 쉬운 형태로 유지
    • 복잡한 추상화 없이도 실제 사용에 유용하며, 선언된 기능만 명확히 작동

Read Entire Article