値としての関数
関数を保存して渡します。
「値としての関数」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
関数は第一級の値
Luaでは、関数は第一級の値です。つまり、関数は単なるデータとして扱えます。変数に保存したり、別の関数に渡したり、関数から返したり、テーブルに格納したりできます。
この1つの考え方が、関数型プログラミングの基盤になります。関数を数値や文字列と同じように扱うことで、柔軟で再利用可能なツールを構築できます。
関数を変数に保存する
関数に付けた名前は、実際には関数の値を保持する変数にすぎません。その値を別の変数に自由に代入できます。
以下の2つの名前は同じ関数を指しているため、どちらを呼び出しても同じコードが実行されます。
local function greet(name)
return "Hello, " .. name
end
local hi = greet
print(greet("Ada"))
print(hi("Lin"))匿名関数
関数を作るために名前を付ける必要はありません。匿名関数はfunction ... end構文で記述し、値として直接使います。
匿名関数をローカル変数に代入する方法は、通常の関数定義と同じですが、インラインで記述します。
local square = function(x)
return x * x
end
print(square(5))
print(square(9))引数として関数を渡す
関数も値なので、別の関数に渡すことができます。別の関数を受け取る関数を高階関数と呼びます。
ここでのapplyは、実行する関数を渡されるまで、どのような処理を行うか知りません。
local function apply(f, x)
return f(x)
end
local function double(n) return n * 2 end
print(apply(double, 10))
print(apply(function(n) return n + 1 end, 10))関数を返す
関数から別の関数を返すことができます。これにより、渡された引数で設定された関数を必要に応じて作成できます。
以下のmultiplierは、呼び出すたびに新しい関数を作成し、指定された係数を保持します。
local function multiplier(factor)
return function(x)
return x * factor
end
end
local triple = multiplier(3)
print(triple(4))
print(multiplier(10)(5))クロージャは変数を捕捉する
返された関数が外側の関数にあるローカル変数を使うと、その変数を捕捉します。関数と捕捉した変数を組み合わせたものをクロージャと呼びます。
捕捉されたfactorは、外側の関数の呼び出しが終了した後も、クロージャが存在する間は保持されます。
local function counter()
local n = 0
return function()
n = n + 1
return n
end
end
local next = counter()
print(next())
print(next())
print(next())テーブルに関数を格納する
テーブルには、ほかの値と同じように関数を格納できます。Luaでモジュールやオブジェクトを構築できるのはこの仕組みのおかげです。テーブルで名前と関数の値を対応付けます。
キーを使って関数を検索して呼び出したり、操作を格納したテーブルを反復処理したりできます。
local ops = {
add = function(a, b) return a + b end,
sub = function(a, b) return a - b end
}
print(ops.add(2, 3))
print(ops["sub"](9, 4))戦略をテーブルに格納する
関数をテーブルに格納すると、キーを使って実行時に動作を選択できます。これにより、長いif-elseの連鎖を分かりやすい検索処理に置き換えられます。
名前で操作を選択すれば、呼び出し側のコードを短く保ち、新しいキーにも簡単に対応できます。
local dispatch = {
upper = string.upper,
lower = string.lower,
rev = string.reverse
}
local function run(name, s)
return dispatch[name](s)
end
print(run("upper", "lua"))
print(run("rev", "lua"))コールバック
コールバックとは、後で呼び出すために渡す関数です。Luaの標準ライブラリでもこのパターンが使われています。たとえば、table.sortは比較関数を受け取ります。
コールバックがルールを決め、ライブラリが反復処理や並べ替えを担当します。
local nums = {5, 2, 9, 1}
table.sort(nums, function(a, b)
return a > b
end)
print(table.concat(nums, ", "))関数には同一性がある
すべての関数の値は、それぞれ異なるオブジェクトです。同じコードを含んでいても、別々の関数リテラルが等しくなることはありません。
ただし、1つの関数を2つの変数に保存した場合は、両方の名前が同じ値を参照するため、等しいと判定されます。
local f = function() return 1 end
local g = function() return 1 end
local h = f
print(f == g)
print(f == h)なぜ重要なのか
関数を値として扱うと、汎用的なツールを一度だけ作成し、渡す関数によって動作をカスタマイズできます。map、filter、部分適用、合成はすべてこの仕組みを利用しています。
このコースの以降の内容では、第一級関数とクロージャを基盤に、実用的なパターンを構築していきます。
確認問題
Luaにおける第一級関数の理解度を確認しましょう。
まとめ
Luaの関数は第一級の値です。変数やテーブルに保存したり、引数として渡したり、別の関数から返したりできます。
外側の関数のローカル変数を捕捉する関数を返すと、クロージャが作成されます。これらの考え方が、これから学ぶすべての関数型プログラミングのパターンの基盤になります。
よくある質問
「値としての関数」レッスンは無料ですか?
はい。「値としての関数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「値としての関数」で何を学びますか?
関数を保存して渡します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「値としての関数」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 値としての関数
- map、filter、reduce
- 部分適用
- 関数を合成する