Lisette — Rust構文ベースでGoランタイムにコンパイルされる小型言語
(lisette.run)- 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<T> で表現- 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<int>を受け取り、Goの明示的な条件文へ変換され、combine関数はResultを検査するGoコードへ変換される
追加情報
- 公式リポジトリ: github.com/ivov/lisette
- MITライセンスで公開されており、2026年時点で Iván Ovejero が開発
1件のコメント
Hacker News のコメント
著者と話してみて、実際にこの言語を使ったわけではないが、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
複雑な参照グラフを扱う問題領域では GC が不可欠であり、Go はユーザーモードのスタック構造のおかげで効率的なメモリモデルを持つ
Go はこうした 高速な CLI ツール の作成にも向いている — 例: wordle-tui
文法が単純で、クロスプラットフォーム対応、ランタイムと GC を内蔵し、“errors as values” の構造、グリーンスレッド、高速な AOT コンパイラなど、多くの利点がある
Go の
deferは有用だが、エラー処理とスコープ規則 はぎこちないTypeScript もこの問題を解決できておらず、むしろもっと悪い。そこで自分で Option 型パッケージ を作って NPM に公開した → fp-sdk
Go にコンパイルされる言語はすでにいくつもある — XGo, Borgo, Soppo など
(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 への知識移転も起きない
intやfloat64は Go の型命名規則に従ったものだ+ではなく.を使うことをよく忘れるGo ランタイムは良いが、言語そのものは 無骨で、改善する意志がないように見える
だからトランスパイラを使うほどなら、よほど Go が嫌いなのだろう
Rust や Rust 系言語が struct と method を分離 している理由が気になる
なぜ struct の中にメソッドを直接定義できないのか不思議だ
また impl ブロックは struct とは異なる ジェネリック制約 を持てるため、複数定義できる
最後に、Rust はデータの 形(Shape) を中心に考えるよう設計された言語だ
Python のように見えるのに Rust や Go にコンパイルされる言語があったら本当に素晴らしいと思う
Lisette は Go の単純さと Rust の複雑さのあいだで 良いバランスを取った言語 に見える
コンパイル速度が Go より大幅に遅くなる理由があるのか、また Rust の機能のうち何を意図的に除外しているのか気になる
例: borrow checking、データ型、async など
Go は学びやすいが機能不足な言語だ
Lisette はその 隙間を埋める言語 に見えるので興味深い
TypeScript が JavaScript を拡張したように、Go に 表現力のある型システム と 厳格なコンパイラ を加えれば、優れたバックエンド言語になるだろう
個人的な提案としては、TypeScript フロントエンドとの 型共有 をサポートしてほしい。これが TypeScript がバックエンドでも人気な理由の一つでもある
Rust の安全性と Go の単純さのあいだで悩むインフラ自動化開発者として、Rust の使い勝手 を Go ランタイムの上に載せるという発想は非常に魅力的だ
今後もプロジェクトの進展を追い続けるつもりだ