デフォルト引数の問題
関数をコールする際、引数を省略してコールできる機能をもつ言語が多く存在する。
ここでは、その機能を「デフォルト引数」と呼ぶ。
デフォルト引数の例として、Lua のサンプルを次に示す。
local function func( x, y )
print( x, y )
end
func( "abc" ) // abc nil
Lua では関数コール時に省略された引数は、 nil として処理される。
上記の func( "abc" )
は、引数 x, y のうち y が省略され、
実行すると abc nil が表示される。
デフォルト引数は、引数が多い関数を呼び出す際に有効な機能である。 特に Lua は、引数の違いによって実行する関数を切り替える関数オーバーロードがないため、 デフォルト引数は良く使われる機能の一つである。
しかし、デフォルト引数は便利である一方、不具合を発生させるリスクにもなる。
そのリスクとは、意図してデフォルト引数を使用しているのか、 それとも、本来指定すべき引数を指定し忘れているのか、を判断出来ないということである。 タイプミス等で関数に渡す引数を間違えることが良くある。 それを判断できないというのはリスクが高い。
Lua の トランスコンパイラである LuneScript でも、同じ問題を抱えている。
次は LuneScript のデフォルト引数のサンプルである。
fn func( val: int! ): int {
when! val {
return val + 1;
}
return 0;
}
print( func( 1 ) ); // 2
print( func( nil ) ); // 0
print( func() ); // 0
このサンプルは、デフォルト引数を持つ func() の関数呼び出しを 3 パターン行なっている。
- func( 1 )
- func( nil )
- func()
LuneScript は Lua と同じで、引数が省略されると nil が指定される。
よって、 func( nil )
と func()
は同義である。
しかし、 func()
が引数の指定忘れではないと、誰が保証できるだろうか?
また、 LuneScript では nilable は必ず省略可能なデフォルト引数になってしまう。
デフォルト引数をサポートする多くの言語では、 デフォルト引数はデフォルト値を定義する必要がある。 一方 LuneScript では、nilable は必ずデフォルト引数になってしまう。
「nil の時でも省略せずに明示すべき」としたくても、 現在の言語仕様ではそれが出来ない。
この辺りを解決する方法を検討している。
ただこれを解決するには、現状の言語仕様との互換を持たせるのは難しいかもしれない。