Baboon: 자동 진화와 태그 없는 바이너리 코덱을 이용한 데이터 모델링

발행: (2025년 11월 30일 오전 05:12 GMT+9)
7 min read

Source: Hacker News

Baboon: 자동 진화와 태그 없는 바이너리 코덱을 갖춘 데이터 모델링

Baboon은 인간 친화적인 선언형 스키마를 제공하고 신뢰할 수 있는 스키마 진화를 강제하는 최소한의 데이터 모델링 언어이자 컴파일러입니다. 컴파일러는 빠른 불변 다단계 DAG 변환으로 동작하며 이해하고 유지보수하기 쉽습니다.

본질적으로, 여러분은 데이터 구조를 정의하고 Baboon이 구현을 생성하도록 합니다. 그런 다음 새로운 버전을 정의하면 Baboon이 구조의 새로운 버전, 이전 구조 버전에서 새로운 버전으로의 변환을 생성하고 자동으로 유도할 수 없는 변환은 직접 제공하도록 강제합니다. 또한 모든 구조에 대해 매우 효율적인 태그 없는 바이너리 인코딩을 제공합니다.

현재 **C#**와 Scala를 생성합니다; 더 많은 백엔드가 곧 추가될 예정입니다.

주요 특징

  • JSON 및 UEBA(초고효율 바이너리 집합, 커스텀 태그 없는 바이너리 포맷)를 위한 자동 코덱 파생
  • 진화 인식 코드 생성: 가능한 경우 마이그레이션을 파생하고, 수동 작업이 필요할 때는 스텁을 출력
  • +, -, ^ 연산자를 이용한 집합 기반 구조적 상속
  • 대수 데이터 타입(adt), DTO(data) 및 열거형
  • 명목 상속의 기본 형태(contract)
  • 네임스페이스, 포함, 임포트
  • 컬렉션(opt, lst, set, map) 및 타임스탬프/UID 기본형
  • 중복 제거된 C# 출력(가능한 한 많은 코드를 재사용해 바이너리 크기 감소)

예시 모델 (v1.0.0)

model acme.billing
version "1.0.0"

root adt PaymentMethod {
  data Card {
    pan: str
    holder: str
  }
  data Wallet {
    provider: str
    token: str
  }
}

리팩터링된 모델 (v2.0.0)

model acme.billing
version "2.0.0"

data Token {
  token: str
}

root adt PaymentMethod {
  data Card {
    pan: str
    holder: str
  }
  // refactored, but same structure as before
  data Wallet {
    provider: str
    + Token
  }

  // new ADT member
  data BankTransfer { iban: str }
}

Baboon은 버전 1.0.0에서 2.0.0으로의 변환(마이그레이션)을 생성합니다. 이 경우 모든 마이그레이션이 자동으로 생성됩니다.

복사‑붙여넣기 예제가 포함된 상세 언어 안내서는 저장소의 docs/language-features.md에서 확인할 수 있습니다.

에디터 지원

  • IntelliJ IDEA 플러그인 – 소스: baboon-intellij
  • VS Code 확장 – 소스: baboon-vscode
  • VSCodium 확장 – VS Code와 동일

제한 사항

  • 템플릿 미지원
  • 열거형, DTO, ADT만 지원
  • 명목 상속은 트레이트 모델에만 제한적으로 지원
  • 제네릭/타입‑생성자는 내장 컬렉션에만 제한
  • 이것은 DML이며 IDL이 아닙니다; 서비스/인터페이스 정의 지원은 매우 제한적
  • 주석이 트랜스파일러 출력에 보존되지 않음
  • 구조적 상속 정보가 트랜스파일러 출력에 보존되지 않음
  • 열거형 멤버에 정수 상수만 연결 가능
  • 뉴타입/타입 별명 미지원
  • 상속 기반 렌즈/프로젝션/변환 미지원

별표(*)가 붙은 항목은 향후 개선될 수 있습니다.

CLI

빌드 구성은 .mdl/defs/actions.md에, 테스트 구성은 .mdl/defs/tests.md에 있습니다.

참고 사항

  • root 타입에 의해 전이적으로 참조되지 않는 모든 타입은 컴파일러 출력에서 제거됩니다.
  • 구조적 상속에서의 사용은 참조로 간주되지 않으므로, 필드로 직접 참조되지 않거나 root로 표시되지 않은 구조적 부모는 제거됩니다.

외부 타입

외부 타입을 사용할 때는 코덱을 올바르게 연결하는 것이 여러분의 책임입니다.

각 외부 타입에 대해:

  1. 커스텀 코덱을 생성합니다.
  2. BaboonCodecs#Register로 생성된 더미 코덱을 오버라이드합니다.
  3. ${Foreign_Type_Name}_UEBACodec#Instance의 세터를 사용해 더미 코덱을 오버라이드합니다.
  4. ${Foreign_Type_Name}_JsonCodec#Instance의 세터를 사용해 더미 코덱을 오버라이드합니다.

외부 타입이 원시 타입이나 다른 생성된 타입이 아니도록 주의하세요. 외부 타입은 제네릭 어디에든 나타날 수 있지만, 올바른 동작을 보장해야 합니다.

개발

빌드 명령

이 프로젝트는 mudyla를 사용해 빌드 오케스트레이션을 수행합니다.

# Format code
direnv exec . mdl :fmt

# Build the compiler
direnv exec . mdl :build

# Run complete test suite
direnv exec . mdl :build :test

# Run full build pipeline (format, build, test)
direnv exec . mdl :full-build

# Run specific test suites
direnv exec . mdl :build :test-gen-regular-adt :test-cs-regular :test-scala-regular
direnv exec . mdl :build :test-gen-wrapped-adt :test-cs-wrapped :test-scala-wrapped
direnv exec . mdl :build :test-gen-manual :test-gen-compat-scala :test-gen-compat-cs :test-manual-cs :test-manual-scala

# Create distribution packages
direnv exec . mdl :build :mkdist

# Build with custom distribution paths
direnv exec . mdl --mkdist-source=./custom/path --mkdist-target=./output :build :mkdist

환경 설정

# Enter the Nix development shell
nix develop

# Or use direnv for automatic shell activation
direnv allow
Back to Blog

관련 글

더 보기 »

스칼라의 기원 (2009)

번역하려는 텍스트를 제공해 주시겠어요? 텍스트를 알려주시면 한국어로 번역해 드리겠습니다.