Lua のユルさと危うさ

スクリプト言語 Lua は,基本的には命令型プログラミング言語であって,オブジェクト指向型言語としての機能は,本来持ち合わせていない。ただ,関数を first-class オブジェクトとして扱えることや, metatable 等の機能を使うことによって,「OOP のようなもの」は実現できるようになっている。

このような「OOP のようなもの」を意識した syntax sugar のひとつとして,「コロン構文」が用意されている。例えば,次のような記述によって「メソッドのようなもの」を定義することができる。

function counter:add(delta)
  self.count = self.count + delta
end

これは,以下の記述と同等に扱われる。

counter.add = function(self, delta)
  self.count = self.count + delta
end

この「メソッドのようなもの」を呼ぶには,次のようにする。

counter:add(10)

これは,以下の記述と同等に扱われる。

counter.add(counter, 10)

(参考: Lua 5.1 Reference Manual, 2.5.8 - Function Calls, 2.5.9 - Function Difinitions

これは便利な機能のように思えるけれど,実際に使ってみると,便利などころか危険な機能のようにも思われてくる。 "xxx:yyy()" とすべきところを "xxx.yyy()" と書いてしまったときに何が起こるか考えてみてほしい。上の Counter の例ならインデックスエラーで止まってくれるかもしれないけれど,場合によってはエラーも起きずに通過してしまうことがある。もちろん,望み通りの動作はしてくれなくて,そのオブジェクトの中身は何となくグシャっと壊されている

それが, "." と ":" の違いだけで発生するんだ。その書き間違いを探すのって,楽じゃないよ! もう, ":" が "☺" に入れ替わってる特殊フォントでも使った方がいいんじゃないか,ってぐらいにさ……。

まあ,これは一例で,他にも「言語としてのユルさ」が仇になってしまっている点が,いくつか見受けられる。 Lua の「ユルさ」は,軽量性と汎用性の高さを両立させるという理想を実現するのに必要な要素ではあるものの,運用時にはそれがデメリットを生み出してしまうことがある。

特に複数人での共同開発を行う際には,スタイルの統一を意識する必要がある。無難な書き方を好む人ばかりだったらいいかもしれないけれど……ユルいがゆえに色々なことができると気付くと,色々なことをやっちゃう人もいるんだ(自分を含む)。

Lua の対抗勢力であるところのスクリプト言語 Squirrel は,単なる syntax sugar ではなく,言語のフィーチャーとして様々な機能のサポートを行っている。そのことの背景には,こういった Lua の「ユルさ」に対するアンチテーゼがあるのだろうと思う。