Glojure: Go를 위한 호스팅된 Clojure 인터프리터

Glojure는 Go 프로그래밍 언어 상에서 호스팅되는 Clojure를 구현하는 인터프리터입니다. 전통적인 포팅 방식과 달리, Glojure는 "호스팅된" 언어입니다. 이는 모든 Go 값이 Glojure 값으로 사용될 수 있고 그 반대도 가능하다는 양방향 관계를 유지함을 의미하며, 이는 Clojure가 JVM 상의 Java와 맺는 관계를 반영합니다.

핵심 기능 및 실행 모델

Glojure는 실행을 위해 tree-walk 인터프리터를 사용합니다. 현재 초기 개발 단계에 있어(저자들은 버그, 누락된 기능, 제한된 성능이 발생할 수 있음을 언급함) 이미 변환된 Clojure 코어 라이브러리의 상당 부분을 지원하며 취미용 프로젝트에 적합합니다.

주요 기술 사양

  • 호스트 요구 사항: Go 버전 1.19 이상이 필요합니다 (현재 설치를 위해서는 go 1.24 권장).
  • 실행 방법: Tree-walk 인터프리터.
  • 호환성: v1 릴리스 전까지는 하위 호환성이 보장되지 않습니다.
  • 버전: 현재 버전은 v0.3.0입니다.

사용 및 배포 옵션

Glojure는 독립형 명령줄 도구로 배포하거나 Go 바이너리에 직접 임베딩할 수 있습니다.

독립형 명령줄 도구 (glj)

glj 명령은 다음과 같은 표준 Clojure 개발 경험을 제공합니다:

  • 대화형 REPL: Vi 및 Emacs 편집 모드, 멀티라인 편집, 탭 완성, 지속적인 히스토리를 지원합니다.
  • 직접 평가: -e 플래그를 통해 셸에서 직접 식을 평가할 수 있습니다.
  • 스크립팅: .glj 스크립트를 독립형 프로그램으로 실행할 수 있는 기능입니다.

Go 애플리케이션에 임베딩

Glojure는 Go 애플리케이션 내에서 스크립팅 엔진으로 사용되어 스란 구성이나 플러그인 시스템을 제공할 수 있습니다. 이를 통해 개발자는 Go의 성능과 Clojure의 표현력을 결합할 수 있습니다. 개발자는 glj.Varruntime.ReadEval API를 사용하여 Clojure에서 Go 함수를 호출하거나 Go에서 Clojure 함수를 호출할 수 있습니다.

Go 상호 운용성

상호 운용성(Interop)은 Glojure의 주요 기능으로, Clojure가 Java 프레임워크에 접근하는 방식과 유사하게 Go 라이브러리에 접근할 수 있게 해줍니다.

표준 라이브러리 지원

Glojure는 기본적으로 fmt, net/http, os, time, sync, regexp를 포함한 수많은 Go 표준 라이브러리 패키지를 위한 상호 운용성을 제공합니다. Clojure의 네임스페이스 구문( / 사용)과의 모호함을 피하기 위해, 슬래시가 포함된 Go 패키지 이름은 변형됩니다. 예를 들어, net/http는 Glojure에서 net:http가 됩니다.

상호 운용성 확장

추가적인 Go 패키지를 노출시키려면 개발자는 gen-import-interop 도구를 사용하여 패키지 맵을 생성할 수 있습니다. 이렇게 생성된 .go 파일은 애플리케이션에 임포트되어 원하는 패키지 내보내기를 Glojure 패키지 맵에 추가합니다.

기술적 차이점 및 비교

타입 매핑

Glojure는 Clojure 타입을 다음과 같이 Go 타입으로 매핑합니다:

Clojure Type Glojure Type Note
long int64
double float64
float float32
byte byte Go의 byte는 부호가 없으며, JVM의 byte는 부호가 있습니다
short int16
int int Go의 int는 플랫폼에 따라 다릅니다 (32/64-bit)
char lang.Char 태그된 rune (32-bit) vs JVM 16-bit
BigInt *lang.BigInt *big.Int를 래핑함
BigDecimal *lang.BigDecimal *big.Float를 래핑함
Ratio *lang.Ratio *big.Rat를 래핑함

다른 Go-Clojure 포팅 프로젝트와의 비교

Aspect Glojure Joker let-go
Hosted Yes No No
Extensible Go interop Yes No No
Concurrency Yes Yes (with GIL) Yes
Clojure tooling No Yes No
Execution Tree-walk interpreter Tree-walk interpreter Bytecode Interpreter

Sources