HighとLow
Highは字下げでブロックを書く.nagi、Lowは波括弧と;で書く.lowです。どちらもNagiの言語です。普段はHighで書き、関数の実装を差し替えたいときにLowを使えます。
このページの目次
HighをLowへ変換する
次をapp.nagiに保存します。
def score(value: i64) -> i64:
return value * 2
def main():
print(score(7))
nagic run app.nagi
nagic lower app.nagi
実行結果は14です。lowerは型・所有権を検査し、build/app/generated.lowにLowを出力します。Lowでは関数をfnで宣言し、ブロックを{ }で囲みます。生成された変数にはletと推論した型が付きます。
手書きLowで関数を差し替える
次を同じディレクトリのnative.lowに保存します。
@replace generated::score
fn optimized_score(value: i64) -> i64 {
return value * 6;
}
nagic check app.nagi --native native.low
nagic run app.nagi --native native.low
今度は42と表示されます。High側の呼び出しはscore(7)のままで、実行する本体がLowのoptimized_scoreに置き換わります。@replace generated::scoreが差し替える対象を指定しています。
差し替え先は、引数の数・型、戻り値の型、asyncかどうかが元の関数と一致する必要があります。対象が存在しない場合や、同じ関数を複数回差し替える場合はエラーです。変更できるのは関数全体です。
generated.lowはコマンドを実行すると再生成されます。変更を残すにはnative.lowへ書いてください。--nativeは差し替えに加えて通常のLow関数も追加でき、Highからその関数を呼べます。設定を保存する方法はプロジェクト設定にあります。
Lowの文法
型、所有権、借用、Resultの扱いはHighと共通です。次はResultを処理する関数の例です。
fn number_or(text: view[str], fallback: i64) -> i64 {
match parse_i64(text) {
case Ok(number) { return number; }
case Err(_) { return fallback; }
}
}
OkとErrの両方が必要です。詳しくはエラー処理を参照してください。
現在のLowは、型付きの変数、view、class(Lowではrecord)、関数、分岐、ループ、async、scopeに対応しています。生ポインター、メモリ配置の指定、手動の確保・解放、SIMD命令、unsafe構文、C ABIは未対応です。Rustの関数を呼ぶ方法はファイルのimportとRust連携にあります。