# Lisette — Rust 문법 기반으로 Go 런타임에 컴파일되는 소형 언어

> Clean Markdown view of GeekNews topic #28268. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=28268](https://news.hada.io/topic?id=28268)
- GeekNews Markdown: [https://news.hada.io/topic/28268.md](https://news.hada.io/topic/28268.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-04-07T06:32:49+09:00
- Updated: 2026-04-07T06:32:49+09:00
- Original source: [lisette.run](https://lisette.run/)
- Points: 3
- Comments: 1

## Topic Body

- **Rust 스타일 문법**을 사용하면서 **Go 런타임** 위에서 동작하는 **소형 언어**로, 두 언어의 장점을 결합한 형태
- **대수적 데이터 타입**, **패턴 매칭**, **Hindley-Milner 타입 시스템**, **기본 불변성** 등으로 **안전성과 표현력**을 강화한 구조
- **Go 패키지 직접 import**, **파이프라인 연산자**, **try 블록**, **task 기반 동시성**을 통해 **Go 생태계와의 상호운용성** 확보
- **컴파일 타임 오류 탐지**, **명확한 진단 메시지**, **LSP 지원**으로 **개발자 경험과 코드 안정성** 향상
- **Lisette 코드가 읽기 쉬운 Go 코드로 변환**되어, 기존 Go 프로젝트와 자연스럽게 통합 가능한 점이 핵심

---

### Lisette 개요
- **Lisette**는 **Rust 문법**을 기반으로 하며 **Go 런타임**으로 컴파일되는 소형 언어
- **대수적 데이터 타입**, **패턴 매칭**, **nil 없음**, **Hindley-Milner 타입 시스템**, **기본 불변성**, **Go 생태계와의 상호운용성**을 특징으로 함
- `cargo install lisette` 명령으로 설치 가능하며, Go의 `fmt`, `io`, `os` 등 패키지를 직접 import하여 사용 가능

### 익숙한 문법
- **Rust와 유사한 문법 구조**를 가짐
  - `enum`과 `match`를 통한 **패턴 매칭** 지원
  - `struct`와 `impl` 블록으로 **메서드 정의** 가능
- **표현식 지향 언어**로, `if`, `let`, 블록 등이 모두 값을 반환함
- **체이닝과 람다**를 지원해 환경 변수 처리나 문자열 조작을 간결하게 표현 가능
- **인터페이스와 제네릭**을 지원하며, `interface` 정의와 `T: Trait` 제약을 통한 제네릭 함수 작성 가능
- **if let** 및 **let else** 구문으로 `Option` 타입을 간결하게 처리 가능

### 안전성
- ## Go 런타임에서 발생 가능한 오류를 컴파일 타임에 탐지
  - `match` 문에서 모든 패턴이 처리되지 않으면 오류 발생
  - `nil` 사용 불가, **Option&lt;T&gt;** 로 결측값 표현
  - **Result** 반환값을 무시하면 경고 발생
  - **비공개 타입을 공개 API에서 노출** 시 경고
  - **불변 변수**를 가변 인자로 전달 시 오류
  - **구조체 필드 누락** 시 컴파일 오류
  - 진단 메시지는 **구체적 코드 위치와 수정 제안**을 함께 제공
  - **LSP(Language Server Protocol)** 지원으로 VSCode, Neovim, Zed 등 주요 에디터에서 사용 가능

### 사용성
- **Go와의 상호운용성**을 중점으로 설계
- **파이프라인 연산자(`|>`)** 로 함수 체이닝을 간결하게 표현
- **try 블록**을 통해 오류 전파를 단순화
- **동시성**은 `task`와 `Channel`을 이용해 Go의 goroutine과 유사하게 구현
- **직렬화 속성(attribute)** 으로 JSON 필드명, 생략, 문자열 변환, 검증 태그 등을 지정 가능
- **panic 복구**를 위한 `recover` 블록 제공, `Result` 타입으로 안전한 오류 처리 가능
- **defer** 구문을 지원해 리소스 정리나 트랜잭션 롤백 보장

### 투명한 컴파일 결과
- Lisette 코드는 **명확하고 읽기 쉬운 Go 코드로 변환**됨
  - `Option`과 `Result` 타입은 각각 `lisette.Option`과 `lisette.Result` 구조체로 변환
  - `match` 구문은 Go의 조건문으로 변환되어 각 분기 처리
  - `?` 연산자는 내부적으로 `Result` 검사 코드로 치환
- 예시로, `classify` 함수는 `Option&lt;int&gt;`를 받아 Go의 명시적 조건문으로 변환되며, `combine` 함수는 `Result`를 검사하는 Go 코드로 변환됨

### 추가 정보
- 공식 저장소: **[github.com/ivov/lisette](https://github.com/ivov/lisette)**
- **MIT 라이선스**로 공개되어 있으며, 2026년 기준 **Iván Ovejero**가 개발

## Comments



### Comment 54798

- Author: neo
- Created: 2026-04-07T06:32:49+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47646843)   
- 저자와 대화해 봤고 직접 언어를 써보진 않았지만, **Lisette**가 흥미롭고 Go보다 명확히 개선된 언어로 보임  
  다만 Go의 한계를 완전히 극복하긴 어렵다고 생각함. 예를 들어, Go의 인터페이스 타입에서 오는 `typed nil` 문제는 Lisette에서 Option으로 처리되지만, 이중 언래핑(`Some(Some(h))`)이 어색해질 수 있음  
  또한 Go의 **defer** 방식은 여전히 불편하며, RAII처럼 자동 자원 해제가 되지 않음  
  TypeScript가 JavaScript를 보완했던 이유는 브라우저에서 실행 가능한 대안이 없었기 때문인데, 이제는 WASM이 있어서 상황이 다름  
  그래서 “Rust가 있는데 왜 Go를 Rust처럼 만들까?”라는 의문을 가짐. 다만 Lisette은 그 중간 지점을 노리는 듯함  
  결국 Lisette은 기존 Go 코드베이스를 개선하거나 Go 런타임을 계속 쓰고 싶은 사람에게 적합한 언어로 보임  
  내가 궁금한 점은 “다음 파일을 Go 대신 Lisette으로 작성하려면 어떻게 시작해야 하는가”라는 **빠른 시작 가이드**의 부재임  
  관련 블로그 글: [Go is still not good](https://blog.habets.se/2025/07/Go-is-still-not-good.html)  
  - Go는 **GC 기반의 동시성 런타임**을 제공한다는 점에서 여전히 독보적임  
    복잡한 참조 그래프를 다루는 문제 영역에서는 GC가 필수적이며, Go의 사용자 모드 스택 구조 덕분에 효율적인 메모리 모델을 가짐  
  - GC 언어에서는 개발 속도가 훨씬 빠름. Rust와 Python으로 챗봇을 만들어봤는데, Rust 경험이 있음에도 Python이 훨씬 빨랐음  
    Go는 이런 **빠른 CLI 도구** 제작에도 적합함 — 예: [wordle-tui](https://github.com/sa-/wordle-tui)  
  - Go는 언어로서 이상한 점이 많지만, **컴파일 타깃**으로는 훌륭함  
    문법이 단순하고 크로스플랫폼 지원, 런타임과 GC 내장, “errors as values” 구조, 그린 스레드, 빠른 AOT 컴파일러 등 장점이 많음  
    Go의 `defer`는 유용하지만 **에러 처리와 스코프 규칙**이 어색함  
  - 블로그에서 언급된 “Go가 NULL을 두 번 실수로 만든 언어”라는 표현이 인상적이었음  
    TypeScript도 이 문제를 해결하지 못했고, 오히려 더 나쁨. 그래서 직접 **Option 타입 패키지**를 만들어 NPM에 올림 → [fp-sdk](https://www.npmjs.com/package/fp-sdk)  
  - Rust의 **async**는 GC가 없어서 Go보다 덜 편리함. 이 점만으로도 Go 런타임을 선택할 이유가 됨  
  
- Go로 컴파일되는 언어는 이미 여러 개 있음 — [XGo](https://github.com/goplus), [Borgo](https://github.com/borgo-lang/borgo), [Soppo](https://github.com/halcyonnouveau/soppo) 등  
  - Borgo와 Lisette은 `(T, error)` 반환을 **Result 타입**으로 단순 치환하지만, 이는 의미적으로 완전히 동일하지 않음  
    예를 들어 `io.Reader.Read`는 `(n!=0, io.EOF)`가 정상 종료를 의미하므로, 단순히 에러로 처리하면 잘못된 동작을 초래함  
  - 컴파일 에러가 **타깃 언어에서 소스 언어로 어떻게 전달되는지** 궁금함  
  
- Lisette의 **에러 메시지 품질**이 인상적임. “help” 힌트가 실제로 유용하게 느껴짐  
  다만 Go로 변환된 코드가 장황해질 수 있어서, 런타임 에러 시 Go 코드에서 디버깅해야 하는 점이 걱정됨  
  또한 기존 Go 코드에서 Lisette을 호출하는 방향이 어려워 보임  
  Lisette이 실험적인 언어인지, 실제 프로덕션을 목표로 하는지 궁금함  
  - 개발자가 직접 답변함: `lis run --debug` 옵션을 사용하면 Go 코드에 `//line source.lis:21:5` 주석이 삽입되어 **스택 트레이스가 원본 Lisette 코드로 매핑**됨  
    LSP는 컴파일 타임 에러를 `.lis` 파일 기준으로 처리함  
    현재는 Go에서 Lisette을 호출하는 기능은 없지만, **Lisette에서 Go 패키지를 임포트**하는 기능이 우선순위임  
    처음엔 실험이었지만, **프로덕션 수준 언어**로 발전시키는 것이 목표임  
  
- Rust와 비슷한 문법을 왜 그대로 가져오지 않았는지 궁금함  
  예: `import "foo.bar"` 대신 `use foo::bar`, `Bar.Baz =>` 대신 `Bar::Baz =>` 등  
  Rust를 아는 사람은 헷갈리고, 모르는 사람은 Rust로 지식이 전이되지 않음  
  - 이런 문법 차이는 사소하며, 핵심은 **Rust의 타입 시스템을 Go에 도입**하는 것임  
    `int`와 `float64`는 Go의 타입 명명 규칙을 따른 것임  
  - 여러 언어를 오가다 보면 문법 유사성이 오히려 **혼란을 유발**함. 예를 들어 PHP에서 `+` 대신 `.`을 써야 하는 걸 자주 잊음  
  - 나도 처음엔 TypeScript 기반의 Rust 스타일 언어를 만들려다, 결국 **Rust 자체가 생각보다 어렵지 않음**을 깨달음  
  - GC 언어에서 Rust 스타일 메모리 모델을 구현하는 건 **매우 비자연적**임. 객체마다 독립된 주소 공간을 가지는 셈이라 복잡함  
  - Lisette은 Rust에서 **영감을 받은 언어**이지 Rust가 되려는 게 아님. **Go 개발자**를 주요 타깃으로 함  
  
- Go 런타임은 좋지만 언어 자체는 **투박하고 개선 의지가 없어 보임**  
  그래서 트랜스파일러를 쓸 정도라면 정말 Go를 싫어해야 할 듯함  
  
- Rust나 Rust 계열 언어들이 **struct와 method를 분리**하는 이유가 궁금함  
  왜 struct 안에 메서드를 직접 정의하지 못하는지 의문임  
  - Rust에서는 struct 필드가 **auto-trait**에 영향을 주기 때문에, 필드를 한눈에 보는 게 중요함  
    또한 impl 블록은 struct와 다른 **제네릭 제약**을 가질 수 있어서 여러 개를 정의할 수 있음  
    마지막으로 Rust는 데이터의 **형태(Shape)** 를 중심으로 사고하도록 설계된 언어임  
  - 개인적으로는 impl 블록이 Go의 메서드와 비슷하다고 느끼며, 어느 쪽이 더 낫다고 보긴 어려움  
  
- Python처럼 보이지만 Rust나 Go로 컴파일되는 언어가 있다면 정말 멋질 것 같음  
  - [Mojo](https://www.modular.com/open-source/mojo)는 Swift 창시자가 만든 **Python 문법 기반의 고성능 언어**임  
  - [Spy](https://github.com/spylang/spy)는 C로 컴파일되는 초기 시도이며, **Nim**도 비슷한 계열의 성숙한 언어임  
  - Nim은 Python과 비슷한 문법에 **정적 타입 시스템**을 갖추고, wasm과 C 등 다양한 타깃으로 컴파일됨  
  - [Static Python Skill](https://github.com/py2many/static-python-skill)은 Python을 정적으로 컴파일하려는 시도임  
  - [Grumpy](https://github.com/google/grumpy)는 Google이 만든 Python→Go 트랜스파일러였지만, **9년째 업데이트 없음** (Python 2.7 대상)  
  
- Lisette은 Go의 단순함과 Rust의 복잡함 사이의 **균형을 잘 잡은 언어**로 보임  
  컴파일 속도가 Go보다 훨씬 느릴 이유가 있는지, Rust 기능 중 어떤 부분을 의도적으로 제외했는지 궁금함  
  예: **borrow checking**, 데이터 타입, async 등  
  
- Go는 배우기 쉽지만 기능이 부족한 언어임  
  Lisette은 그 **빈틈을 메우는 언어**로 보여서 흥미로움  
  TypeScript가 JavaScript를 확장한 것처럼, Go에 **표현력 있는 타입 시스템**과 **엄격한 컴파일러**를 더하면 훌륭한 백엔드 언어가 될 것임  
  개인적인 제안은 TypeScript 프론트엔드와의 **타입 공유**를 지원하는 것임. 이것이 TypeScript가 백엔드에서도 인기 있는 이유 중 하나임  
  
- Rust의 안전성과 Go의 단순함 사이에서 고민하는 인프라 자동화 개발자로서, **Rust의 사용성**을 Go 런타임 위에 얹는 아이디어가 매우 매력적임  
  프로젝트 발전을 계속 지켜볼 예정임
