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 で実行した例です。(実行には時間がかかります)