Unlambda on Scala
まめめもさんの Unlambda インタプリタを書いてみた - まめめも よりも綺麗な実装を書こうとしたら、等価なものができてしまいました。(^^; Scala で callcc はできるのでしょうか?
実装のコツとしては、遅延評価は後回しにするといいです。今、組み込み関数で外だしされているのは、vしか残っていませんが、最初は、全部外出しにしていました。` と . の2つから作っていき、eval()を作るよりも先に、「Unlambda ソース -> 自分の記述する言語のソース」を手作業で変換をかけてみると、どうやって実装するといいか、見えてきます。
関数型言語の処理系の実装の題材としては、非常にいい題材だと思います。
object Unlambda extends Application { // 表記を短縮するための型 type a = Any type f = a => a // 1行分読み込む val line = new scala.collection.mutable.Queue[String] line ++= readLine.split("").drop(1).filter(_ != " ") // 組み込み関数 v def v(x:a):f = v _ // 式の評価 def eval():() => a = { val c = line.dequeue c match { case "`" => val f1 = eval val f2 = eval () => { val f3 = f1() if(f3 != None) f3.asInstanceOf[f](f2()) // 先行評価 else (x:a) => (f2()).asInstanceOf[f](x) // 遅延評価 } case "." => val x = line.dequeue; () => (y:a) => { print(x); y } case "e" => () => (x:a) => exit case "i" => () => (x:a) => x case "k" => () => (x:a) => (y:a) => x case "r" => () => (x:a) => { println; x } case "s" => () => (x:a=>f) => (y:f) => (z:a) => (x(z))(y(z)) case "d" => () => None case "v" => () => v _ case _ => () => c } } eval }