P4P: Racket (scheme)のシンタックスを一見Python的にするという提案

http://shriram.github.com/p4p/

スキームによるfibonacci numbersの定義はこんな感じだろう。


(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
それをこうしようというのがこの提案だ。

deffun: fib(n) =
if: <(n, 2)
n
else:
+(fib(-(n 1)), fib(-(n, 2)))

提案者はBrown大学の教授 http://www.cs.brown.edu/~sk/ コンピュータサイエンスの教育を研究課題としているようで、LISPschemeの括弧を減らしてもっと広く受け入れられる言語にすることを狙っているようだ。

テング的にはpythonシンタックスが好きなんで、これでschemeのパワーが駆使できたら素晴らしいと思う。目についた特徴をつまんでみる:

do: などにより括弧を省く

do:などのキーワードにより文章の「始まり」を明確化する。これによりかなりの数の括弧が省けるよういなるらしい。よくある構文はこんな感じになる:

  • fun: args in: {BODY}
  • defstruct: memo has: (key, ans)
  • if: [do: .. ] elseif: .. else: ..

「:」で終るブロックを開始するキーワードはpythonにヒントを得たというが、inとかhasとか英語の意味にマッチした使い方はperl(moose)的な感じもする。

Racketのマクロによる実装

別のパーサなどは使っていない。これにより、Racketとの親和性が保証される。

引数はカンマで分離foo(bar,baz)

関数名と「(」が逆転: (foo bar baz) が foo(bar, baz)に。

これでアゴル系社会で違和感が減る?

しかし、prefixにこだわる: +(1,2)

「一般社会」にコビ売ってもinfix(1+2)を使ったらスキームじゃない。「+」も普通の関数と同等のものだ、ということを教えるのに重要だとしている。教育を念頭においているところが伺われる。

tokenはracketのをそのまま使用

インデントはセマンティックスに影響しない

ここはpythonと根本的に違う。教授は厳密なインデント形式を良しとしているが、空白がセマンティックスに影響するのはこのましくないというスタンスだ。つまりエディタなどのツールはpythonのようにインデントを強制するべきだが言語自体はそれを強要しないということのようだ。これにより、マシンにより生成されたコードはスペースを自由に扱えるが、人間向けのコードは画一のインデントスタイルを使うことにより、python的な読みやすさ効果を得られる。つまりインデントによる文法ではないが、目指すところはpythonと同じと受けとっていいと思う。

個人的にはリスプシンタックスが嫌いというわけではないが、a-z以外のところに指をやるのを極力避けたい。「シンタックスなんて外見で本質的なものでない」、とか思っていたが、pythonを使うようになって考え方が変った。ゾーンに入りやすいシンタックスとそうでないのがある。理由は簡単な経済原理だ。shiftを押したり、右端小指を延さないと行けないところにあるキーを頻繁に要求されると、流れにのれない。hoffman encodingの原理をプログラミング言語に応用すると、高頻度のものはなるべく短くエンコーディングした方がいいことになる。ブロックの終始マーカーは高頻度な要素だ。C系言語では{}。これのコストは左でシフトを押して、右小指を延す。その上にリターンを押す場合が殆どだ。「shift+]+RET」。LISP系だと「shift+0+RET」。Rubyは「end+RET」。pythonはhoffman encodingで最適化された「RET」だけになる。これがpythonの最大のアドバンテージだと感じる。とにかく[a-z\n]を打ちまくっていれば動くコードが出てくる。変なところに小指をやらない分、ゾーンに入りやすい。pythonはエルゴノミクス的に最適化された言語ってことだ。少なくとも自分には。

しかし、パワーではschemeにかなわない。もしschemepythonのフローに入れたら切り替えてもいいかもしれない。