
2026/06/21 3:53
Show HN: Tiny – 内联 Go 原生関数を備えた解釈型動的言語
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Tiny は、Go で実装された新しい同時実行対応の高性能プログラミング言語およびランタイムシステムであり、生のパフォーマンスを優先する独自バイトコード仮想マシン(
.tbc)を搭載しています。効率的なインタプリタによる一般論理処理と、ホットループや文字列演算といったクリティカルなコードパス用に最適化された Just-In-Time(JIT)コンパイラを組み合わせたハイブリッド実行モデルを採用しています。このシステムは、固有のロックブロック内にある自動的にミューテックスが解放されるメカニズムと、孤立した VM 状態空間の利用によって、デッドロックなどの一般的な同時実行問題を防止します。
開発者は、動的型付け(オプションで静的ヒント可)を備えたモダンな開発体験、組み込みの Language Server(LSP)、OS レベルの並列処理を実現する
spawn、継承ではなくクラス合成を実現する embed、堅牢なパターンマッチングのための match ブロックといったユニークな機能を含む開発環境を利用できます。片付けは defer 構文により管理されます。インストールは Windows、Linux、macOS Apple Silicon を含め、簡単に行えます。コアエンジン以外に、Tiny は高スループット Web サービス(http)、スキーマ検証(validate)、タイマー(time)、ネイティブ配列演算(array)、デスクトップ UI オートメーション(desktop)のためのツールを含む豊富な標準ライブラリを提供します。ユーザーは、外部パッケージとのシームレスな相互作用を可能にする WebAssembly に Go コードを直接コンパイルする特別な native fn ブロックを作成することで、ランタイムをさらに拡張できます。要するに、Tiny はコンパイル言語のスピードとインタプリタ言語の柔軟性を組み合わせつつ、スレッド安全性と開発容易さを保証します。本文
Tiny: 超高速並行バイトコード仮想マシン
Tiny は、高性能な並行型バイトコード仮想マシンと、そのランタイムを Go で実装した動的言語です。Tiny は、開発のスピード感と堅牢なマルチスレッド実行環境を両立するプラットフォームです。
概要
Tiny は、並行プログラミングに特化した言語およびランタイムシステムです。
- バイトコード生成: ソースファイルを高度に最適化された仮想マシン(
拡張子)上のコンパクトなスタック指向バイトコードに変換します(スロット方式のローカルストレージ採用)。.tbc - ハイブリッド実行モデル:
- 一般的なロジックにはインタプリタを採用し、パフォーマンス重視箇所では**即時コンパイル(JIT)**を行う。
- 主要機能:
- OS 層による並列スレッド処理
- ホストメモリに反映されたパック配列
- 連結可能なスキーマ検証ライブラリ
- ネイティブ WebAssembly エクステンション
- 内蔵言語サーバー(LSP)
リソースリンク
インストール方法
公式リリースページから、対応 OS のバイナリを用意します。
バイナリダウンロード先
| OS | ファイル名 |
|---|---|
| Windows | |
| Linux | |
| macOS (Apple Silicon) | |
セットアップ手順
- ご自身の OS に合ったバイナリをダウンロードします。
- ファイル名を
(Windows はtiny
)に統一します。tiny.exe - バイナリディレクトリを作成し、システム PATH への追加を準備します(例:
または Windows の~/.tiny/bin
)。%USERPROFILE%\.tiny - システムの PATH 環境変数に上記ディレクトリを追加して完了です。
※ソースコードからのコンパイルについては公式ドキュメントをご参照ください。
言語仕様の特徴
動的型付けとオプショナルなヒント
- デフォルトは動的型付けですが、ラピッドプロトタイピングも可能。
- オプショナルな静的型ヒント(変数、引数、戻り値)を適用できます。
- ユニオンやジェネリクスによる型システムを提供します。
import std "io"; // 未定型変数 let data = "untyped string"; // 明示的な型ヒント const port: number = 8080; fn calculatePayout(base: number, multiplier: number): number { return base * multiplier; } io.println(calculatePayout(100, 1.5));
構造的インターフェースと形状検証
- **構造体指向型(Shape-based)**アプローチを採用。オブジェクトは実行時に関係するインターフェースに対して検証されます。
- JIT エンジンはオブジェクトの形状を追跡し、線形メモリのフィールドオフセットを活用してチェックを最適化します。
import std "io"; interface Task { title: string done: bool } fn printTask(t: Task) { let status = t.done ? "Completed" : "Pending"; io.println(`${t.title} - Status: ${status}`); } // 構造的なマッチング printTask({ title: "Write Compiler Tests", done: true }); printTask({ title: "Optimize VM Dispatcher", done: false, priority: 1 });
デストラクチャリング代入
およびlet
宣言において、オブジェクトと配列のデストラクチャリングをサポート。const- ネストされたパターン、デフォルト値、プロパティの名前変更に対応。
import std "io"; const user = { name: "Alice", age: 30, address: { city: "NYC", zip: "10001" } }; // オブジェクトと配列のデストラクチャリング let { name, address: { city } } = user; io.println(`${name} lives in ${city}`); let coordinates = [10.5, 20.8, 30.0]; let [x, y] = coordinates; io.println(`X: ${x}, Y: ${y}`);
クラスの合成と埋め込み
- **継承よりも合成(Composition)**を重視。
キーワードにより、クラスのインスタンスに振る舞いを委譲可能。親クラスで欠落している場合、自動的に埋め込まれたインスタンスから解決されます。embed
import std "io"; import std "json"; class Logger { field messages = [] fn log(message: string) { this.messages.push(message); io.println(`Log: ${message}`); } fn dump() { return this.messages; } } class SessionManager { field active = true embed logger // 埋め込みクラス fn init() { this.active = true; this.logger = Logger(); this.log("Session manager initialized"); // 委譲された呼び出し } fn close() { this.active = false; this.log("Session closed"); } } let session = SessionManager(); session.close(); io.println(json.pretty(session.dump()));
パターンマッチング
ブロックは、リテラル値、変数、列挙体(enum)、ユニオンプATTERN、ガード条件をサポート。match- 列挙体のバリアントからデータを抽出する主要手段です。
import std "io"; enum Result { Ok(value), Error(message) } fn process(res: Result) { match res { Result.Ok(val) if val > 0 => io.println(`Success: ${val}`), Result.Ok(_) => io.println("Success with zero or negative value"), Result.Error(msg) => io.println(`Error: ${msg}`), _ => io.println("Unknown state") } } process(Result.Ok(42));
スコープ付きクリーンアップ(Defer)
文は、現在のスコープを退出する直前に関数呼び出しをスケジュール。defer- 早期リターンや例外が発生した場合でも、デフォルトの実行が保証されます。
import std "fs"; import std "io"; fn processFile(path: string) { io.println("Opening file stream..."); let file = fs.open(path); defer fn() { io.println("Running defer block: closing file stream."); file.close(); } io.println("Processing file data..."); } processFile("README.md");
並行モデル
並列スレッド実行
- OS 層のマルチスレッドを活用した並列操作の実行。
キーワードで新しい実行ルーチンを開始し、隔離された VM の状態空間上で動作します。spawn- イベントループとは異なり、利用可能なすべての CPU コアを横断してタスクを並行的に実行します。
import std "io"; import std "time"; let worker = spawn () fn() { time.sleep(1000); return "Worker thread complete"; }; io.println("Main thread proceeding..."); let result = await worker; io.println(result);
スレッドセーフと Mutex ロッキング
- 共有状態は、ミューテックスやネイティブロックブロックで調整可能。
- コンパイラーが自動的にデッドロック防止を確保します(ロック脱出時の自動解放)。
import std "io"; import std "sync"; let counter = 0; const m = sync.mutex(); fn increment() { lock m { counter = counter + 1; } }
即時コンパイル (JIT)
ホットなバイトコードパスをネイティブの WebAssembly に翻訳する多機能な JIT コンパイルエンジンを内蔵。
機能点
- リージョンアウトライニング: トップレベルコードや関数内のホットループを特定し、特殊化した JIT リージョンにアウトライン化します(手動カプセル化不要)。
- パックされたオブジェクト配列: 一様な形状のオブジェクト配列に対し、ホストメモリのミラーリングとフィールドカラムポインタテーブルを活用し、相互運用性のオーバーヘッドを回避します。
JIT セーフなベストプラクティス
最大のパフォーマンスを得るための指針:
- クロージャーを避ける: 変化する外部変数をキャプチャするとインタプリタで実行され、非効率になります。
- 同期処理を保つ:
関数は対象外です。async - 型ヒントの提供: JIT の特殊化を助けます(例:
)。: number - 文字列連結:
を使用し、大規模ビルド時の効率性を確保します。stringBuilder
// JIT 最適化が極めて高い関数の特徴: // ・明示的な型指定 // ・同期処理 // ・外部変数のキャプチャなし // ・ループ構造の利用 fn computeSum(n: number, initial = 0): number { let total = initial; for let i = 0; i < n; i++ { total += i; } return total; }
インライン Go エクステンション (WebAssembly)
特定の Go パッケージが必要なロジックに対し、ネイティブ
fn を用いてソースファイル内に直接 Go コードを記述できます。TinyGo 経由で WebAssembly にコンパイルされ、ランタイム時に読み込まれます。
import std "io"; import std "time"; native fn calculateSha256(input: string): string { go { import "crypto/sha256" import "encoding/hex" h := sha256.Sum256([]byte(input)) return hex.EncodeToString(h[:]) } } const text = "Tiny runtime speed"; io.println(`SHA256: ${calculateSha256(text)}`);
標準ライブラリ
validate (スキーマ検証)
- データスキーマを定義・強制するための連結可能 API。
- オブジェクト、配列、ユニオン、変換をサポート。
import std "validate"; import std "io"; const userSchema = validate.object({ username: validate.string().trim().nonempty().min(3).required(), age: validate.number().int().positive().default(18), tags: validate.array(validate.string()).default([]) }); const result = userSchema.safeParse({ username: " alice " }); if result.success { io.println(result.data.username); // "alice" }
url (URL 処理)
- URL のエンコードとデコーディングに対応。
time (タイマーと計測)
- 実行遅延、パフォーマンス計測、管理されたタイマーをサポート。
import std "io"; import std "time"; let timer = time.interval(1000, fn() { io.println("Tick"); }); time.sleep(5000); timer.cancel();
array (ネイティブ演算子)
- 配列操作用のネイティブ演算子を内蔵。
,find
,filter
,map
,reduce
,sort
,flat
を備えます。findIndex
http (Web サーバー/クライアント)
- 高スループットな完全並行 Web サーバーおよびクライアント。
- ルートベースのマルチプレキシングと最適化された JSON シリアライゼーションをサポート。
import std "http"; import std "io"; let server = http.server(8080); server.get("/users/:id", fn(req: http.RequestObject) { return http.json({ id: req.params["id"], query: req.query }); }); io.println("Web server listening on port 8080"); server.start();
ui (WebView デスクトップアプリ)
- HTML/CSS/JS を使用した軽量デスクトップコンテナ。
- Tiny 関数との直接バインディングが可能。
import std "ui"; const win = ui.new(true); win.setTitle("Tiny UI"); win.setSize(500, 400); win.callback("registerClick", fn(arg) { return "Click registered"; }); win.setHtml("<h1>Hello Tiny</h1>"); win.run();
desktop (OS オートメーション)
- キーボード、マウス、クリップボードの相互作用を自動化するためのネイティブインターフェースラッパー。
import std "desktop"; desktop.moveMouseSmooth(800, 600); desktop.click(); desktop.type("Tiny Automation");
ツールとエコシステム
コマンドラインインターフェース (CLI)
: スクリプトのコンパイル・実行(未変更ファイルはキャッシュを跳过)。tiny run <file>
: バイトコードと VM ランタイムを単一ネイティブバイナリにバンドル。tiny pack <file> -o <binary>
: アプリケーション、コンパイル済みプラグイン、アセットをパッケージ化。tiny dist <file> -o <dir>
: 内蔵言語サーバーの起動。tiny lsp
内蔵言語サーバー (LSP)
VS Code などとの統合には
tiny lsp を実行してください。主な機能:
- インポートの整理: 自動ソートと未使用インポートの削除。
- セマンティック回復: 構文エラー時でも診断情報を継続提供。
- 型の狭化: フローベースの型推論(例:null チェック後の型判定)。
- リファクタリングの安全性: オブジェクトキーや変数の正しいシンボル解決。