ラムダ式です。
funとの違いは、引数の受け取りに多値代入と同じルールが使われるという点です。
つまり、
foo : |x, y| x + y; foo(1, 2).p;
は、
fun foo(X){x, y : X; return x + y;} foo((1, 2)).p;
とだいたい同じ意味を持ちます。
ラムダ式では、引数が少ない場合には最後の引数がundefinedになってランタイムエラーにならないのに比べて、関数では引数が足りないのでランタイムエラーとなります。
また、多い場合にもラムダ式は最後の引数が多値になるのに比べて、関数では引数が多いのでランタイムエラーとなります。
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)<head(right))? pack(head(left), merge(tail(left), right)): pack(head(right),merge(left, tail(right))); merge_l : |left, right| pack(head(left), merge(tail(left), right)); merge_r : |left, right| pack(head(right), merge(left, tail(right))); merge : |left, right| (left&&right)? merge_lr(left, right): (left? merge_l(left, right): (right? merge_r(left, right): ())); sort_2nd : |left, right| merge(sort(left), sort(right)); sort_split : |hd, tl, tl2| tl2? pack(hd, sort_split(tl,tl2)): pack(hd,tl); sort : |l| (is_list(l)? sort_split(sort_2nd(split(l.size()/2-1, l))): l);