Luaで関数型プログラミングサポート
新しい言語を覚える段階では、別の言語と比べすぎない方がいいと思ってるので、今まで、欲しいと思った関数が無くても、Luaの概念を知るためになるべく素のLuaの範囲で書いてきました。(あえて、Lisp的に書くために関数を追加するようなことは避けてきました)
しかし、いくつかLuaでWebアプリケーションを書いてきたので、そろそろお遊びをしてもいい頃かと思い、map reduce apply を実装してみました。utilsというモジュールを作りました。
utils.lua
module(..., package.seeall)
function clone(list)
local result = {}
for k, v in pairs(list) do
result[k] = v
end
return result
end
function map(f, list)
local result = {}
for _, v in pairs(list) do
table.insert(result, f(v))
end
return result
end
function reduce(f, list)
local list = clone(list)
local result = table.remove(list)
for _, v in pairs(list) do
result = f(result, v)
end
return result
end
function apply(f, args)
return f(unpack(args))
end
map は、一つしかリストを取得できない手抜き版です。
test.lua
使い方
require "utils"
local ary = {1, 2, 3, 4, 5}
local ret = utils.map(function(x) return x * 2 end, ary)
print("map:", table.concat(ret, ", "))
--> map: 2, 4, 6, 8, 10
print("sum:", utils.reduce(function(x, y) return x + y end, ary))
--> sum: 15
print("max:", utils.apply(math.max, ary))
--> max: 5
LuaでWebアプリケーションを書く中で、素のLuaに接してみて、やはりfor文を沢山書く必要があるのが、面倒だなと感じました。だいたい、Webアプリケーションでのデータ操作なんて、写像が大半なんだから、mapを使った方が分かり易いと思う。とにかく、関数型プログラミングのためのサポート関数も簡単に書けました。
stdlib
stdlibというLuaを便利にするライブラリがありました。
stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pretty-printing and getopt. The whole thing can be loaded with ‘require “std”‘, or modules can be used individually.
LuaForge: stdlib – general Lua libraries: Project Info
もちろん、リスト操作系のmapとか、reverseとか、filterとか、fold(r|l)とかだけでなく、tostringの拡張とかも入ってるみたいです。prototype.js的に、標準ライブラリの中まで拡張しているようです。また、機会があれば、中身をよく見てみたいです。こんなに、豪勢に拡張して、Luaの良さを侵食してないかちょっと心配w