Tiny: インラインGo拡張を備えた並行動的言語

Tinyは、Goで構築された高性能かつ並行なプログラミング言語およびランタイムシステムです。動的なコーディングの機敏性とマルチスレッドのランタイムエンジンを組み合わせ、ソースファイルを.tbc命令にコンパイルするスタックベースのバイトコード仮想マシンを利用しています。

マルチティア実行とJITコンパイル

Tinyは、一般的なロジック用の効率的なインタプリタと、パフォーマンスが重要なパス用のJust-In-Time (JIT) コンパイラで構成されるマルチティア実行モデルを採用しています。JITエンジンは、頻繁に実行されるバイトコードパスをネイティブなWebAssemblyに変換し、ネイティブに近い速度を実現します。

リージョン・アウトライニング

コンパイラは、関数本体やトップレベルコード内のホットループを自動的に識別し、それらを特化したJITリージョンへとアウトライン化します。これにより、開発者が手動でロジックを関数にカプセル化することなく、スクリプトやベンチマークをネイティブの速度で実行できます。

パックド・オブジェクト・アレイ

VMとネイティブ間の相互運用オーバーヘッドを削減するため、JITは均一な形状を持つオブジェクトを含む配列に対してホストメモリのミラーリングを実装しています。フィールド・カラム・ポインタ・テーブルを使用することで、ランタイムは線形メモリ内でオブジェクトのプロパティに直接アクセスできます。これらのパックド・アレイは、動的な成長とWasm側の最適化をサポートしています。

JIT最適化のベストプラクティス

開発者は、以下の特定のコーディングパターンに従うことで、JITパフォーマンスを最大化できます:

  • 型ヒントを使用する: 明示的なヒント(例:: number)を提供することで、JITが特化したマシンコードを生成するのに役立ちます。
  • クロージャのキャプチャを避ける: 可変な外部変数をキャプチャする関数は、JITではなくインタプリタによって処理されます。
  • 同期状態を維持する: async 関数は、現在JITコンパイルの対象外です。
  • 文字列操作: 文字列の結合操作はJITによって加速されますが、大規模な構築には標準ライブラリのstringBuilderが推奨されます。

言語仕様

Tinyは、迅速なプロトタイピングと堅牢なアプリケーション開発のために設計されており、動的型付けと構造的バリデーションを組み合わせています。

動的型付けと構造的インターフェース

Tinyはデフォルトで動的型付けですが、変数、パラメータ、および戻り値の型に対して、ジェネリクスやユニオンを含むオプションの静的型ヒントをサポートしています。また、オブジェクトが実行時にインターフェースに対して検証される構造的型付け(形状ベースの検証)を使用しています。JITエンジンは、オブジェクトの形状を追跡し、線形メモリのフィールドオフセットを利用することで、これらのチェックを最適化します。

高度な構文機能

  • 分割代入: ネストされたパターン、プロパティ名の変更、およびデフォルト値を使用して、オブジェクトや配列の分割代入をサポートしています。
  • クラス構成: embed キーワードを使用することで、クラスは他のクラスインスタンスに振る舞いを委譲することができ、深い継承よりも構成を優先します。
  • パターンマッチング: match ブロックは、リテラル値、変数、列挙型、ユニオンパターン、およびガードをサポートしており、enumのバリアントからデータを抽出するための主要なメカニズムとして機能します。
  • スコープ付きクリーンアップ: defer 文は、早期リターンやエラーに関わらず、周囲のスコープが終了する直前に、関数呼び出しが即座に実行されることを保証します。

並行処理とスレッド

Tinyは、イベントループモデルとは異なり、並列実行のためにOSレベルのマルチスレッドを利用します。spawn キーワードは、隔離されたVM状態空間上で新しい実行ルーチンを開始し、利用可能なすべてのCPUコアを跨いでタスクを並列に実行することを可能にします。

共有状態は、ミューテックス(mutexes)とネイティブなlock ブロックによって管理されます。コンパイラは、デッドロックを防ぐために、実行がブロックを離れる際にミューテックスが自動的に解放されることを保証します。

WebAssembly経由のインラインGo拡張

Tinyは、native fn ブロックを使用することで、開発者がソースファイル内に直接Goのコードを記述することを可能にします。これらのブロックはTinyGoを介してWebAssemblyにコンパイルされ、ランタイムでロードされるため、Tinyスクリプト内で特定のGoパッケージを使用することが可能になります。

標準ライブラリとツール

Tinyは、さまざまなユースケースに対応する包括的な標準ライブラリを提供しています:

  • validate: オブジェクト、配列、およびユニオンのスキーマ検証のためのチェイン可能なAPI。
  • http: ルートベースのマルチプレキシングを備えた並行Webサーバーおよびクライアント。
  • ui: HTML/CSS/JSを使用し、Tinyの関数への直接的なバインディングを備えたWebViewベースのデスクトップコンテナ。
  • desktop: キーボード、マウス、およびクリップボードの操作のためのOS自動化ツール。
  • time, url, および array: タイミング、URLエンコーディング、およびネイティブな配列操作のためのユーティリティ。

CLIとエコシステム

Tiny CLIは、いくつかの主要なコマンドを提供します:

  • tiny run <file>: バイトコードキャッシュを使用して、冗長な再コンパイルを避けるためにスクリプトを実行します。
  • tiny pack <file> -o <binary>: バイトコードとVMランタイムを単一のスタンドアロンなネイティブ実行ファイル(約13MB)にまとめます。
  • tiny dist <file> -o <dir>: プラグインとアセットをパッケージ化します。
  • tiny lsp: エディタ統合(例:VS Code)のための言語サーバーを開始します。型絞り込み、セマンティックな復元、およびリファクタリングの安全性を提供します。

コミュニティの視点

プロジェクトは大きな技術的幅広さを示していますが、一部のユーザーは、GoやPythonを直接使用する場合と比較して、どのような具体的なユースケースがあるのか疑問を呈しています。あるユーザーは、Tinyがアドホックな構成管理システムのための高レベルなスクリプティング言語として特に効果的である可能性を提案しました。

"i'm wondering if it can beat just installing go though. I think it'd be interesting to build a adhoc config mgmt system w/ this and use it as a high level scripting language."

Sources