Agenda
- metatable
- environment
- upvalue (と closure)
- LuaJIT ffi
- Luvit (とcoroutine)
- ANSI C 準拠で依存関係が少ないため、ポータビリティが高い
- メモリ使用量が少ない
- 高速に動作する
- C/C++で書かれたコードとの連携がとても簡単
{% left %} {% end %} {% right %} まつもとゆきひろ、rubyの作者 {% end %}
- metatable
- environment
- upvalue
- 重要なvariantである、LuaJITが5.1ベースなため
-- metatable はluaの基本データ型'table'にすぎません
local mt = {
-- like JS prototype,
baz = "var",
-- like PHP magic method, "__get" or ruby's method_missing
__index = function (t, k)
return '' .. k .. k
end,
-- like C++ operator + ()
__add = function (o1, o2)
return o1.name .. ' and ' .. o2.name .. ' are forever friends'
end,
}
-- それをsetmetatableというAPIを使って他のテーブルに対して設定します
local o1 = setmetatable({ foo = 'foo', name = 'zynga' }, mt)
local o2 = setmetatable({ baz = "hoge", name = 'facebook' }, mt)
print(o1.foo, o1.bar, o1.baz) --> foo barbar var
print(o2.foo, o2.bar, o2.baz) --> foofoo barbar hoge
print(o1 + o2) --> zynga and facebook are forever friends
- 例えば継承はmetatableにmetatableを設定することで実現される(JSと同じですね!)
- mt1 =(is metatable of)=> mt2 =(is metatable of)=> mt3
- Luaでクラスベースのオブジェクト指向を書いていると、そのことにとても意識的になる
global = nil
sandbox = {}
function modify_global()
global = 'modify global should sandboxed'
end
modify_global()
print(global) --> modify global should sandboxed
print(sandbox.global) --> nil
global = nil
setfenv(modify_global, sandbox)
modify_global()
print(global) --> nil
print(sandbox.global) --> modify global should sandboxed
function factory(num)
local seps = '|'
return function(str)
return (string.rep((str .. seps),num - 1) .. str)
end
end
f = factory(3)
print(f('abc')) --> abc|abc|abc
(referred variable) <=(referred from)= (upvalue scope) <=(referred from)= (refer function)
function factory(num)
local seps = '|'
return function(str)
return (string.rep((str .. seps),num - 1) .. str)
end
end
f = factory(3)
print(f('abc')) --> abc|abc|abc
print(debug.getupvalue(f,1)) --> seps | Luaは多値を返すことができます
print(debug.setupvalue(f,1,'/')) --> seps
print(f('abc')) --> abc/abc/abc
- もっと著名な動的言語rubyやpythonなども、高速化の工夫ののぞけば、本質的には同じことを行っていて、それに文法という名のsyntax sugarを与えているだけといえる。
- Luaでは、直接にその部分をプログラマーがコントロールするため、本質的な部分が見えやすい
- バインディング書かなくていい!(つまりオーバーヘッドもない)
- JIT compileが有効な場合、ダイレクトなC関数呼び出しや、Cの構造体操作などはCのコンパイラと同じマシンコードを生成する
- 実用的な例でも、ほぼC/C++と同等な速度が出ている
- Cocosというより、Obj-C自体をLuaJIT ffiを使ってbindしたような実装
- Cocosのクラスごとにbindingなんか書かなくていい
- x2 - x4 faster than node.js (symple hello world http server)
- ただ、現状の実装ではmeteorのfiberみたいなものなので、本質的ではない。
- いちどあきらめてたみたいだけど、LuaJITのcoroutineがかなり低コストだと知って、もう一度考え直すってMLでいってた。
- これは期待
- Luaは組み込み系のスクリプト言語ではかなり有力
- 組み込みデバイスではブラウザみたいなでかいコンポーネントなんていらない
- OSの上でLuaを使ってシンプルにwebアクセスする形で機能を実装するというのはかなりリーズナブルな選択に見える
- zstats,MapReduceのような離散的な計算だけでなく、気象シミュレーションのような連続量をあつかう大規模計算が必要になってくるはず
- クラウド側におけるGPUコンピューティングはさけられないように思う
- LuaJIT、特にffiはローレベルプログラミングとの親和性の高さから科学計算のロジック部分を記述するためのプラットフォームとなりうる。
- 実際、LuaJITを科学計算のフロントエンドとして使うフレームワークについての研究ってたくさんある(SPLAYとか)
- 多数の組み込み機器の中でLuaが動き、
- 多数のGPUクラウドマシンの中でLuaが動く