kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

無名関数リテラルの追加

Onion開発再開しつつある日記といいつつ、めったにOnionのことが話題に上ることが無い日記だが、先月は久しぶりにOnionをいじってたので、それについてちょっと書いてみる。

今回の主な変更は無名関数リテラルの追加。今までも、Javaの無名クラスみたいな機能(+エンクロージングスコープの普通の変数を触れる機能)はあったのだけど、もうちょっと軽量に書けるものがほしかったので追加してみた。

構文は、

#(x: Object, y: Object) { 
  return x$String + y$String;
}

みたいな感じ。ついでに、mapやfoldlなどのライブラリ関数も追加してみた。

Iterables::map(["A", "B", "C"], 
  (x: Object) { return x$String + "1"; }
); // ["A1", "B1", "C1"]
Iterables::foldl(["A", "B", "C"],
  (x: Object, y: Object) { return x$String + y$String; } // "ABC"

みたいに書ける。Genericsがまだ無いので引数の型は全部Objectという糞仕様だが、このへんはそのうちなんとかしたい。

ちなみに、実装は凄く単純で、

#(n: Object) { ... }

という式があらわれたら、引数の数に応じて

#Function1.call(n: Object) { ... }

のように、従来からOnionにあった無名クラスリテラルに変換するだけ。ぶっちゃけて言うと、Scalaの無名関数の実装方法をまねただけ。