Kotlin には REPL 機能があります。対話型実行環境ですね。さらに、拡張関数を定義できるなど、かなり柔軟なコードが書ける言語でもあります。
今回は演算子の拡張関数を利用することで、 ()
と {}
だけで任意の処理を動かすようにしてみます。 Ook 言語を利用しています。
コードを読み解くために、まずは拡張関数の定義を見ていきます。
1 | typealias Brace = () -> Unit |
文に出てくる単体の {}
は () -> Unit
という型になります。これを Brace
と呼ぶこととします。
さらに Brace
を、 Brace
を一つ引数に取る関数のように実行( invoke
)させられるようにします。ここで、 Kotlin では関数に 1 つの関数を引数として渡すときは ()
を省略し、 {}
を使って書けるということを思い出してください。
これにより、 {}{}
は Brace2
オブジェクトを表すことができます。
オーバーロードしている関数に渡す場合、 hoge()
、 hoge({})
、 hoge({}{})
という3つのパターンができることになります。
続いて、プログラムの開始と終了を表す記述を定義します。上のコードに出てきていますが、 (({}{}){})
が BracketsOok
のインスタンスを表すようにします。ここの ()
を省略すると曖昧になって上手くいきません。
1 | operator fun invoke(): BracketsOok {} |
BracketsOok
もまた関数のように実行( invoke
)できるようにし、 3 つの先ほどのパターンを利用して内部状態を変化させることでコードとして蓄積させます。最後に、 (({}{}){})
を渡すと記述終了とし、蓄積したコードを実行します。
括弧の列をそのまま単体で main
関数に書いてもいいですが、タイトルの通り REPL 上にすると括弧しかないようなプログラムになります。以下が IntelliJ IDEA 2017.1 で実行した例です。(実行には時間がかかります)