今年習得する言語として Lua を選択した。
主に VM の実装がどのようになっているのか、という方面に興味があるんだけど、いじり倒す予定なので言語としての Lua も極めておこうかと思う。
雰囲気はこんな感じ。
function foo() local s, e = string.find("ばなな", "なな") print(s, e) end local bar = foo bar()
- 構文は Fortoran の流れをくむ
- 関数は多値を返す
- 関数に可変長引数を渡せる
- すべての数値は倍精度浮動小数点数
- 関数がファーストクラスオブジェクト
- マルチバイト文字を適切に扱えない
- 配列の添字は 1 から
構文
構文を begin、end で構造化するのは、C 言語に組み込んで人目でそれとわかるようにするため、だと思う。Pro*C(ってまだあるの?)の SQL を全部大文字で書く、みたいな感じだ。
タイプ量が多いし、強調するとうるさいし、対応する括弧に飛ぶみたいなことができないので、あまり好きではないんだけど、理由があってこういう構文なんだから致し方ない。
関数は多値を返す
今時のスクリプト言語なら、多値を返せるのは当たり前だったりする。Perl、Ruby、Python など。Ruby は多値を配列で扱っているっぽいけど、Lua はスタックに積んで管理している。
関数に可変長引数を渡せる
可変長引数の扱いがかなり楽。標準関数の print もプロトタイプは print(...) となっていて可変長引数を受け取る。上の例では関数の戻り値を一旦変数に入れているが、以下のように直接渡すことも可能。
print(string.find("ばなな", "なな"))
関数がファーストクラスオブジェクト
もちろんクロージャも扱える。Lua ではクロージャを扱いやすいように upvalue(上位値)という独自の概念を取り入れている。要するに親スコープの変数ということなんだと思うんだけど、詳しいことはこれから。
マルチバイト文字を適切に扱えない
上記例では文字列に日本語を使用しているけど、これは期待通りには動かない。標準ライブラリはすべてシングルバイト文字のみを想定していて、スクリプトがどのようなエンコードで書かれているかによって、結果が違ってくる。特にスクリプトが Shift_JIS だった場合、第二バイトに 0x5C がある文字で問題が発生する("表" とか)。
UTF-8 を使えば致命的な問題は起こらないけど、ライブラリは文字数ではなくバイト数で換算するから、それを踏まえてスクリプトを組まなければならない。
つまり、
「そうだ、スクリプトでは文字列を扱わなければいいんだ!」
ということなんだと思います(というわけでノベルゲームの組み込み言語には全く向かない)。
配列の添字は 1 から
これも、なんか理由があるんだと思うんだけど、なんだろうなー。
C の実装を見ると、1 開始にしたいがために、要所要所で -1 している箇所があって、多大な努力の末、Lua スクリプトには 1 開始の配列が提供されている(ように見える)。そこまでする理由がわからない。
ちなみに Lua には厳密には配列はなくて、すべて連想配列なので、自分で無理やり添字 0 から開始させることも可能。ただ、連想配列を添え字の若い順にトラバースする iparis 関数などでは、添字 0 はなかったことにされてしまう。
組み込み向けで動的言語でオブジェクト指向だけどクラスベースではなく、関数の取り回しが簡単で正規表現もサポートしている言語、なんだか JavaScript に非常によく似ているきがしませんか?
いつか JavaScript との比較を記事にしてみようと思います。