関数

関数の定義と呼び出しを学びます。※モジュール分割(import)は現行では未実装のため、本ページ末尾にロードマップとしてまとめます。

現行仕様(change.md, 2026-08)

戻り値の型は fn name(...) -> 型 の-> 構文です。-> を省略した書き方は動きません。通常は return を明示しますが、ブロック末尾に置いた if / match は返り値の tail 式として扱われ、各分岐が値を返せば return なしで関数の戻り値になります(change.md 2026-08 で対応)。 途中の式は return で明示してください。


関数の定義

戻り値あり

filename.ngs
fn add(a: i32, b: i32) -> i32 {
    return a + b
}

末尾 if / match を戻り値に(change.md, 2026-08)

関数のブロック末尾(} 直前)に置いた if / match は、全分岐が値を返せば return なしでそのまま戻り値になります。else が無い経路など、値を欠く分岐があるとコンパイルエラーになります。

filename.ngs
enum Op { Add Sub }

fn classify(n: i32) -> string {
    if n > 0 { "pos" } else { "non-pos" }   // 末尾の if が戻り値になる
}

fn apply(op: Op, a: i32, b: i32) -> i32 {
    match op {                             // 末尾の match が戻り値になる
        Add => a + b,
        Sub => a - b,
    }
}

fn must_return(x: bool) -> i32 {
    if x { return 1 }                      // else が無い → エラー
}

戻り値なし

戻り値がない場合は -> を書きません(-> void は不可)。

filename.ngs
fn greet(name: string) {
    println(name)
}

引数なし・文字列を返す

filename.ngs
fn get_version() -> string {
    return "1.0.0"
}

関数の呼び出し

filename.ngs
val result = add(10, 20)   // 30
greet("Alice")              // Alice
val ver = get_version()     // "1.0.0"
println(result)

再帰関数

filename.ngs
fn factorial(n: i32) -> i32 {
    if n <= 1 {
        return 1
    }
    return n * factorial(n - 1)
}

val result = factorial(5)  // 120
println(result)

エクスポート(Wasm / C 連携)

現行仕様(v0.2.0)

export は関数宣言の前置にのみ使えます。export "C" fn ... の形を書き、Wasm や C ABI から呼び出せるようにします。変数を export する「export 文」は使えません(export fn ... は誤り)。

utils.ngs
// utils.ngs
export "C" fn add(a: i32, b: i32) -> i32 {
    return a + b
}

export "C" fn multiply(a: i32, b: i32) -> i32 {
    return a * b
}
bash
# WebAssembly 向けにビルド(外部から add / multiply を呼べる)
nagiscript wasm utils.ngs -o utils.wasm

関数型・クロージャは未対応

ロードマップ(未実装)

関数を値として扱う「関数式」(val f = fn(x) { ... })、関数型フィールド(handler: fn(...))、高階関数、クロージャは現行ではサポートされていません(不安定)。関数の動的切り替えが必要な場合は、enum のバリアントを match + if で分岐して実装してください。

filename.ngs
enum Op { Add Sub }

fn apply(op: Op, a: i32, b: i32) -> i32 {
    match op {
        Add => return a + b,
        Sub => return a - b,
    }
}

val result = apply(Op.Add(), 10, 5)  // 15
println(result)

モジュール / import(ロードマップ)

ロードマップ(未実装)

import は未実装です。複数ファイルへの分割はできず、import "std:io" のような標準モジュールも存在しません。現在は単一ファイルにすべての関数を記述します。複数ファイル分割・std: モジュール・パッケージ管理は将来の予定です。


メソッド(impl ブロック)

現行仕様(v0.2.0)

メソッドは impl ブロックで定義します。文字列組み込みの s.len() / s.to_upper() のようなメソッドは現行では定義されていません。※ impl と self の詳細は「構造体と列挙型」を参照してください。

filename.ngs
struct Counter {
    n: i32,
}

impl Counter {
    fn incr(self: Counter) -> Counter {
        return Counter { n: self.n + 1 }
    }
}

fn main() {
    val c = Counter { n: 1 }
    val c2 = c.incr()
    println(c2.n)  // 2
}