世界を動かす技術を、日本語で。

ジャネット: 軽量で表現力豊かな現代リスプ

2025年7月27日原文(janet-lang.org)

概要

Janet はシステムスクリプトや他プログラムへの組み込みに適した動的言語。 C99準拠 で実装され、主要OSで動作し、移植性が高い。 スレッド・ネットワーク・イベントループ 内蔵など、他の埋め込み言語より多機能。 REPLやビルドツール、豊富な標準ライブラリを提供。 エディタや外部ライブラリ連携 も充実し、学習や導入が容易。

Janetの主な用途

  • システムスクリプト言語 としての利用
  • 他プログラムへの組み込み 用途
  • プロトタイピングや動的システム開発 での活用
  • C99 で実装されており、 Windows・Linux・macOS で動作
  • 標準Cでない機能(動的ライブラリロード等)は 単純実装、移植性重視
  • 埋め込みやすさ多機能性 の両立
    • スレッド、ネットワーク、イベントループ、サブプロセス管理、PEG(正規表現ライク)など内蔵

Janetの特徴

  • 最小構成 :1バイナリのみで即利用可能
  • スレッド・ネットワーク・イベントループ の標準サポート
  • クロージャ・ガーベジコレクション 対応
  • グリーンスレッド(継続) のファーストクラスサポート
  • 配列/タプル・ハッシュテーブル・文字列 の可変/不変両対応
  • マクロ・末尾再帰最適化 サポート
  • Cとの直接連携 (抽象型・C関数呼び出し)
  • 動的Cライブラリロード
  • 字句スコープ・REPL・インタラクティブデバッガ
  • PEG(Parsing Expression Grammars) を標準搭載
  • 500以上の関数・マクロ がコアライブラリに収録
  • jpm によるスタンドアロン実行ファイル生成
  • janet.c/janet.h をプロジェクトに追加するだけで導入可能

コード例

(defn sum3 "Solve the 3SUM problem in O(n^2) time."
  [s]
  (def tab @{})
  (def solutions @{})
  (def len (length s))
  (for k 0 len (put tab (s k) k))
  (for i 0 len
    (for j 0 len
      (def k (get tab (- 0 (s i) (s j))))
      (when (and k (not= k i) (not= k j) (not= i j))
        (put solutions {i true j true k true} true))))
  (map keys (keys solutions)))
(let [arr @[2 4 1 3 8 7 -3 -1 12 -5 -8]]
  (printf "3sum of %j: " arr)
  (printf "%j" (sum3 arr)))
  • 簡単なHello World 例もサポート
    • (print "hello, world!")

Janetの使い方

  • REPL起動 :janetバイナリを引数なしで実行
  • ヘルプ表示-hフラグ指定
  • スクリプト実行janet myscript.janet
  • REPLでドキュメント表示(doc)コマンド
  • コマンド例
    • (+ 1 2 3)6
    • (print "Hello, World!")Hello, World!
    • (os/exit) → REPL終了

主なコマンドラインオプション

  • -h:ヘルプ表示
  • -v:バージョン表示
  • -e code:Janetコードを直接実行
  • -l lib:モジュールを事前にインポート
  • -c source output:ソースをイメージにコンパイル
  • その他、デバッグ・警告・エラー制御など多数

モジュール・ライブラリ

  • GitHubに多数の補助プロジェクト
  • jpm install で簡単インストール
    • Circlet:HTTPサーバ
    • Joy Web Framework:Web開発用フレームワーク
    • JSON:JSONパーサ・エンコーダ
    • SQLite3:データベースバインディング
    • WebView:HTML+CSS UIの生成
    • Jaylib:Raylibバインディング(2D/3Dゲーム開発)
    • JHydro:暗号化ライブラリ
    • JanetUI:libuiバインディング

エディタサポート

  • Neovim・Vim・VSCode・Emacs・Sublime Text・Kakoune・TIC-80・Helix など主要エディタ対応
  • Zulip でエディタ・ツール議論エリアあり

コミュニティ・ドキュメント

  • Zulip Instance (https://janet.zulipchat.com)で活発な議論
  • GitHub Discussions もサポート(Zulipの方が機能豊富)
  • Janet Docs で公式ドキュメント&ユーザー事例を共有
    • 誰でも事例追加可能、学習支援

Janet は、 埋め込みやすさ高機能性 を両立した動的言語。 主要OS対応・導入容易・豊富な標準機能・活発なコミュニティ で、 スクリプト・組み込み・プロトタイピング など幅広い用途に最適。

Hackerたちの意見

ジャネット独自の何かってある?ちょっと見ただけだけど、ほとんどがちょっと違う構文と「モダン」な標準ライブラリを持ったスキームみたいに見える。なんで自分の好きなスキーム(ガイル)からジャネットに乗り換える必要があるの?

全然スキームじゃないよ!結局、コンスセルもないし。クロージャーっぽい感じ(マップが至る所に、コレクションAPI、不変データ構造)で、1MBの実行ファイルが10MB未満のRAMで動くんだ。ファイバーはすごく面白いし、エラーハンドリングにも使われてる。PEGについてはまだ理解できてないけど。

ガイルについてはあんまり知らないけど、ジャネットは開発がかなり楽だったよ。バイナリも小さくて、raylibやいくつかの小さなCライブラリを簡単にラップして埋め込めた。これで配布がすごく楽になる。自分のシンプルな2Dゲームのjaylib(raylib)コードはこんな感じ。ls -laoh build/app -rwxr-xr-x 1 worthless 2.8M 27 Jul 17:28 build/app otool -L ./build/app ./build/app: /usr/lib/libSystem.B.dylib (互換性バージョン 1.0.0, 現在のバージョン 1356.0.0) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (互換性バージョン 1.0.0, 現在のバージョン 24.0.0) /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (互換性バージョン 1.2.0, 現在のバージョン 706.41.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (互換性バージョン 1.0.0, 現在のバージョン 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (互換性バージョン 1.0.0, 現在のバージョン 1.0.0) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (互換性バージョン 45.0.0, 現在のバージョン 2674.3.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (互換性バージョン 150.0.0, 現在のバージョン 4034.0.0) /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (互換性バージョン 64.0.0, 現在のバージョン 1951.0.4) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (互換性バージョン 1.0.0, 現在のバージョン 1226.0.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (互換性バージョン 300.0.0, 現在のバージョン 4034.0.0) /usr/lib/libobjc.A.dylib (互換性バージョン 1.0.0, 現在のバージョン 228.0.0) これらはほとんどのOSXマシンに標準的にあると思うし、Linuxシステムでも似たような感じ。LLMはジャネットを扱えないみたいで、クロージャーだと思い込んで色々とおかしくなっちゃう。

ジャネットはスクリプトに使うことが多いかな。特に外部とやり取りする必要があるスクリプトには、起動が速くて標準ライブラリが充実してるから(特にJSONの操作やHTTPSリクエスト、PEGでのパース、マップにデータを保存するのに便利)。大きなプロジェクトでは、モジュール性やパフォーマンス、メタプログラミングが重要になるからガイルを使うことが多いけど。とはいえ、最近は両方にクロージャーを使ってるよ(スクリプトを実行するのにbabashkaを使ってる:https://babashka.org/)。

2023年のアドベント・オブ・コードのほとんどをジャネットでやったけど、すごく良い経験だった。PEGをできるだけ使うようにして、オーバーキルな時もあったけど、他のパーサーや正規表現に比べて読みやすさや使いやすさが気に入った。依存関係がない小さな言語であるのもいいね。どこにでもインストールしてるし、携帯のtermuxにも入れてる。スクリプトにぴったり。ネイティブなクロージャーのことを夢見てたけど、ジャネットはそれに近い。すべてを持ってるわけじゃないけど、サイズや依存関係のコストがずっと低い。シンプルで使いやすく、RPi Zeroでもちゃんと動く。

大きな違いは、ジャネットのプログラムを追加の依存関係やランタイムなしで実行ファイルにコンパイルできること。これで配布がすごく楽になる。FFIもかなり簡単だし。

Guileが気に入ってるなら、Janetに乗り換える価値はないかもね(でも速いけど)。ただ、絶対にSchemeではないよ。もっと言うと、ネイティブコンパイルされたスクリプト最適化されたClojureみたいな感じ。

Janetのいいところは、Schemeと比べて、似てるけど互換性のない言語のファミリーじゃなくて、一つの言語だってことだね。

ネイティブコンパイラや型はあるの?基本的に、SBCLのパフォーマンスに近づけるのかな?Common Lispよりもクリーンなものがあって、画像サイズもずっと小さいといいな。もしそれで decent なパフォーマンスもあれば、買いだね。

これはCommon Lispの代わりにはならないよ。ガイルと同じニッチにいるけど、かなり速い。

Janetはjpmを使ってスタンドアロンの実行可能ファイルにコンパイルできるよ。

Janetは多くの動的言語よりも速いバイトコードVMを使ってるけど、SBCLのネイティブコンパイルのパフォーマンスには及ばないね。ドキュメンテーション用のオプショナルな型アノテーションはあるけど、最適化用ではないよ。

Hacker Newsで議論の続きを見る