リスト連結(cons)を利用して見やすくした言語xxxを考える。
さて、1と2と3のリストは各言語で以下のようにかける。
lisp xs = (1 2 3)は xs = (1.(2.(3.()))) clean xs = [1,2,3]は xs = [1:[2:[3:[]]]] haskell xs = [1,2,3]は xs = 1:2:3:[] ocaml xs = [1;2;3]は xs = 1::2::3::[]
さて、ここで、xxxという言語を考えてみる。
xxx xs = [1,2,3]は xs = 1 2 3 [] または[1...[2...[3...[]]]]
consの連結演算子はなくて、識別子の連続がコレすなわち、cons演算すると言う形だ。
このxxx言語で(define (a b c) (+ a b))を書くと
[define,[a,b,c],[+,a,b]]
である。これは、consを利用すると以下の用に変形できる。
[define,[a,b,c],[+,a,b]] define[[a,b,c],[+,a,b]] define[a,b,c][[+,a,b]] define(a[b,c])[[+,a,b]]
ここで、()は優先順位を示すための括弧である。
a bは[a,b,[ ] ]か、[a,[b] ]かを区別する方法が必要なためである。
define(a[b,c])[ +[a,b] ], a[1,2],
これで、3が返るようになる。
ということが考えられる。
このxxx言語が自分が作ろうとしている言語として使おうと思った場合の問題点は
define(a[b,c])[+[a,b]],a[1,2]
と
[define,[a,b,c],[+,a,b]],[a,1,2]
の内部データ表現は同じであることだ。
内部データ表現が同じなので、データの操作をするときは結局、リスト操作するだけのことになる。
(fname (a argv) prog)としてデータをとりだせばいいのだろうけど。
たとえば、matchという構文があったとして、
[match,a, [x1, 1], [x2, 2] ] 変形して match(a)[ x1[1], x2[2] ]
とかけるとして、
match(a)[ (dummy (fname argv) [body]) [ print["関数名:",fname,"\n","引数:",argv,"本体:",body,"\n"] ], (dummy name[body] ) [ print["変数名:",name,"\n","値:",body,"\n"] ], ]
と言った風書けるだろう。どっか間違えてるかもしれないけど。
[match,a, [[dummy,[fname ... argv], body], [print,"関数名:",fname,"\n","引数:",argv,"本体:",body,"\n"]], [[dummy, name, body], [print,"変数名:",name,"\n","値:",body,"\n"]], ]
となるといったかんじ。これで解決になっているかどうかはよくわからないけど、マッチングは出来そうである。
出力がどの形になるかをユーザーが決められないのが問題だと言う点は変わらない。