lamdaの記号をどうするかという問題はあるものの、 実際に動かしてみないとイメージが掴めないので、 ごそごそとparse.yをいじってみる。 半日ほどのハックで動くようになった。
NODE_ARGSの構造が変化してしまった。 Yarvに迷惑がかかるかな。
とりあえず、動いてはいるようだ。 これをコミットしたものか。
で、実装した新lambdaはlambdaに対応する記号の部分だけ lexerをいじれば簡単に変更できる。
今のところ、最初の案の通り「->」を使っているのだが、 「 が来るのは激しく気持ち悪い気もしますが……">関数型言語の文化圏からすると引数の前に -> が来るのは激しく気持ち悪い」という指摘も受けている。ここで案についてまとめておこう。
もともとの案。実はPerl6から来ている。Perl6ではRubyのブロック相当を実現する文法として、 「->」が使われており、たとえばfor文が
for list -> x { ... }
のような文法になっている。「->」でパラメータに代入しているというイメージか。 また、ここから派生してクロージャは「-> x { ... }」で表記している。
Perl6はRubyと文化圏が近いため、参考にするのは悪くない、ような気もするが、 そもそもPerl6はいつ実用化されるのか、とか、使われないんじゃないだろうか、 とかいう懸念もある。この記法はブロックとして使われるときには(代入を想起させるので)、 そんなに悪くないんだけど、単体のlambda式として考えると
proc = ->(x, y) { ... }
という記法で、あんまり関数っぽくない。
Haskellではlambdaにバックスラッシュが用いられている。 これは「\」がギリシャ文字のlambda(λ)に似ているから、らしい。
それは分からないでもないが、UNIX文化圏ではエスケープの意味が強すぎるので 受け入れられないような気がする。
proc = \(x, y) { ... }
では、エスケープされた括弧というイメージが大きすぎるのではないか。 文化の違いというのは大きいものだ。
あと、フォントによっては「¥」マークになってしまうのも痛い。
じゃあ、バックスラッシュ二つ重ねるのはどうだろう。
proc = \\(x, y) { ... }
ひとつだけよりはマシのような気がする。が、
ary.each \\(x) { ... }
という使われ方を考えると、視覚的なヒントが少な過ぎる。 この記号を採用した場合にはlambdaとしてだけ使い、 ブロックの記法には使わないようにすべきだろうな。
この案も「¥」マーク問題を無視できない。
ま、結局はブロックとlambdaのどちらに重きを置くかという点のような気がする。 もともと現在のlambdaのパラメータ指定がメソッドの引数と同一でないのが最大の不満だったので、 lambdaの方を強調すべきなのかもしれないが。
現時点では、各案に順位を付けられるほど考察が進んでいない。
長女の吹奏楽の発表会で県民会館へ。
ついこの間始めたばかりなのにもう発表なのか、と思わないでもないが、 一生懸命やっているようだった。もっとも、彼女の演奏している音が識別できたわけではないが。 団体だとその辺は有利だよな。本人曰く、「めっちゃ緊張した」そうだが。
同じ1年生でもパーカッションの娘は、出来がはっきりわかっちゃうから大変だよなあ。
#' は駄目ですか?
コメントですからねえ。> #'
ここはやはりPrologっぽく「-:」でどうでしょう……といいつつ意味として合うのかすらよく解らないのですが
if() とか elsif() みたく記号じゃなくて文字にすればよいのでは
> if() とか elsif() みたく
そもそもが lambda というキーワードを導入したくないという話だったような。
lambdaはわりと広く使われていますからねえ。予約語を増やすのはローカル変数とぶつかったときに悲しいので、最後の手段にしたいです。lambdaでなくてfuncとかなら名前としてはそんなにダメじゃないと思うんですけどねえ。
仮引数をブロックの外に出すことに抵抗を感じます。
ary.each {|x| ...}からary.each->(x=1){...}にすると、x=1がeachの呼び出し前に実行されるような錯覚に陥りません?あと、do...end はどうなるんでしょう。
個人的には、|...|を<...>や<|...|>のように対応関係がつく文字(列)に変更するのが好きです。
取りすがりさん:
Prologは:-ですね:P
引数がブロックの外に出ることについてはじきに慣れると思います。
あと、今までの例では ->(x){...} と書いていますが、{...}の部分は当然 do ... endで置き換えられます。
最後に|...|を「なにか」に変更するアイディアですが、これが結構難しくてですね。オプショナル引数を扱えるためには閉じる記号として式の一部として登場する記号は使えないし(だから > はダメ)、|>のような長いのも好みではありません。なんか良いアイディアはないかなあ。
やっぱ、lambdaを予約語化するのかなあ(そんなに乗り気じゃない)。
f()はどうでしょうか?
proc = f(x, y) { ... }
->を逆向きにして<-とか<=はどうでしょう。
proc = <-(x,y) {...}
分かりにくいかな...
proc <= (x,y) {...}
とか書けるといいのかなー。
その二つは比較と区別がつきませんから。
引数がブロックの外に出なければ、割と自由に開始記号を決められるような気がするんですが。
{->(x,y) ...}
{<-(x,y) ...}
{<=(x, y) ...}
{=>(x, y) ...}
{<(x, y) ...}
{=(x, y) ...}
{>(x, y) ...}
しかし、こうやって変な記号を導入してゆくと、どんどんperlと同じようなヨゴレ言語になってゆく予感。
デフォルト引数を書いたら最後にカンマを書かなければならないようにする、というのはどうでしょうか。
{|x,y=5|10,| ...}
λ に似せて >. とか >, とか。冗談です…(問題解決してないし)。
>* 引数リストに前置する
という条件をまげて、「引数リストに後置で構文解析をがんばる」という選択肢は無理ですか?
yaccでは無理ですね。先読みが1しかないから。
無限先読みができるコンパイラ・コンパイラを使うか、手書きの構文解析器に変更すれば不可能ではないですが、そのコストに見合うほどの選択肢ではないように思います。