English

関数

LuneScript の関数定義、呼び出し、および高度な機能について説明します。

定義

関数は fn キーワードを使って定義します。

// 引数なし、戻り値なし
fn hello() {
    print( "Hello" );
}

// 引数あり、戻り値あり
fn add( val1: int, val2: int ): int {
    return val1 + val2;
}

公開関数

モジュール外に公開するには pub を付けます。公開関数はトップレベル(最上位スコープ)でのみ定義可能です。

pub fn globalFunc() { print("global"); }

多値返却

LuneScript は複数の値を一度に返すことができます。

fn div_mod( a: int, b: int ): int, int {
    return a / b, a % b;
}
let d, m = div_mod( 10, 3 );
print( d, m ); // 3, 1

多値返却の注意点 (Lua/LuneScript の仕様)

関数呼び出しを引数として渡す場合、最後の引数として渡された場合のみ、全ての戻り値が展開されます。

fn func(): int, int { return 1, 2; }

print( func() );      // 1, 2 (すべて展開)
print( func(), 10 );  // 1, 10 (2つ目の戻り値は捨てられる!)
print( 0, func() );   // 0, 1, 2 (すべて展開)

意図せず戻り値が捨てられる事故を防ぐため、LuneScript では多値を引数として渡す際、明示的に ** を付けることを推奨しています(将来的に必須になる可能性があります)。

fn func(): int, int { return 1, 2; }
fn func2( ... ) {}
func2( func()** ); // 多値をすべて渡すことを明示

クロージャと匿名関数

名前のない関数(匿名関数)を作成し、変数に代入したり関数の引数として渡すことができます。

fn run( cb: form ) {
    cb();
}
let val = 10;
run( fn() {
    print( val ); // 外部変数をキャプチャ (クロージャ)
} );

Form (関数型)

関数の型を表すには form キーワードを使用します。ただし、単なる form 型は「任意の引数、任意の戻り値を持つ関数」という広すぎる型(実質 stem! のようなもの)です。

特定の厳密なシグネチャを持つ関数型を定義するには、form 宣言を使用します。

// int を受け取り int を返す関数型 'IntFunc' を定義
form IntFunc( val: int ): int;

fn exec( f: IntFunc, v: int ) {
    print( f( v ) );
}

exec( fn( v: int ): int { return v * 2; }, 10 ); // 20

可変長引数

... を使用して可変長引数を定義できます。

fn dumps( ... ) {
    let list = [ ... ]; // リストに変換
    foreach val in list {
        print( val );
    }
}
dumps( 1, "test", true );

型を指定したい場合は、Generics を使用するか、リストで受け取る設計を検討してください。

引数の省略

Nilable 型の引数は、呼び出し時に省略可能です。省略された場合 nil が渡されます。

fn opt( val: int! ): int {
    return unwrap val default 0;
}
print( opt( 10 ) ); // 10
print( opt() );     // 0 (val is nil)

省略を明示するために ## を使うことができます(opt( ## ))。これは「意図して省略した」ことをコード上で明確にするためです。