====== Lambda ======
ラムダ式です。
funとの違いは、引数の受け取りに多値代入と同じルールが使われるという点です。
つまり、
foo : |x, y| x + y;
foo(1, 2).p;
は、
fun foo(X){x, y : X; return x + y;}
foo((1, 2)).p;
とだいたい同じ意味を持ちます。
ラムダ式では、引数が少ない場合には最後の引数がundefinedになってランタイムエラーにならないのに比べて、関数では引数が足りないのでランタイムエラーとなります。\\
また、多い場合にもラムダ式は最後の引数が多値になるのに比べて、関数では引数が多いのでランタイムエラーとなります。
===== Example =====
foo : |x, y| x + y;
foo(10, 20).p;
基本的には1つの式しか書くことができず、returnせずともその評価値が戻り値として使われますが、次のように{}とreturnを使って複数式を記述することもできます。この場合にはreturnしないとundefinedが返る(値が返らない)ので注意してください。
foo : |x, y|{
X : x + 10;
Y : y + 10;
return X + Y;
};
foo(10, 20).p;
ラムダ式といえば再帰表現ですよね! {}を使わない場合は三項演算子を使って条件分岐します。
fact : |x, y|((x==1)? y: fact(x-1, (y?y*x:x)));
fact(5).p;
多値の結合(このプログラムだと末尾がundefinedな多値を結合しようとするとうまくいきませんが!)
sub_cat : |v, hd, tl|(tl? sub_cat(sub_cat(v, tl), hd): (v? (|x|x)(hd,v): hd));
cat : |l| sub_cat(null, l);
cat(((1, 2), 3), (3, 4, (5, 9))).p;
完全に愚かですが多値のマージソートを書きました。思ったよりも速かったですがやっぱり遅かったです。
pack : |x| x;
head : |hd, tl| hd;
tail : |hd, tl| tl;
is_list : |l| l.class===Values&&l.size()>1;
split_pack : |d, hd, tl| pack(pack(d, hd), tl);
split : |n, hd, tl|(n==0? pack(hd, tl): split_pack(hd, split(n-1, tl)));
merge_lr : |left, right| (head(left)