1
2/* Operators for functional programming.
3 * Examples:
4 *  a:b:c:{}       ->  {a,b,c}
5 *  "Sin" @ a      ->   Sin(a)
6 *  "Sin" @ {a,b}  ->   Sin(a,b)
7 *  "Sin" /@ {a,b} ->   {Sin(a),Sin(b)}
8 *  1 .. 4         ->   {1,2,3,4}
9 */
10
11
12/* a : b will now return unevaluated (rather than cause error of invalid argument in Concat) if neither a nor b is a list and if one of them is not a string
13*/
14RuleBase(":",{head,tail});
15Rule(":",2,20,IsList(head) And Not IsList(tail) ) Concat(head,{tail});
16Rule(":",2,30,IsList(tail) ) Concat({head},tail);
17Rule(":",2,10,IsString(tail) And IsString(head)) ConcatStrings(head,tail);
18UnFence(":",2);
19
20
21RuleBase("@",{func,arg});
22Rule("@",2,1,IsList(arg)) Apply(func,arg);
23Rule("@",2,2,True       ) Apply(func,{arg});
24
25Function("/@",{func,lst}) Apply("MapSingle",{func,lst});
26
2710 # (count'from_IsInteger .. count'to_IsInteger)_(count'from <= count'to)
28   <-- Table(i,i,count'from,count'to,1);
2920 # (count'from_IsInteger .. count'to_IsInteger)
30   <-- Table(i,i,count'from,count'to,-1);
31
32/* NFunction("new'func", "old'func" {arg'list}) will define a wrapper function
33around  "old'func", called "new'func", which will return "old'func(arg'list)"
34only when all arguments are numbers and will return unevaluated
35"new'func(arg'list)" otherwise. */
36LocalSymbols(NFunction'Numberize)
37[
38NFunction(new'name_IsString, old'name_IsString, arg'list_IsList) <-- [
39	MacroRuleBase(new'name, arg'list);
40	MacroRule(new'name, Length(arg'list), 0,	// check whether all args are numeric
41		UnList({IsNumericList, arg'list})
42	)
43
44		/* this is the rule defined for the new function.
45		// this expression should evaluate to the body of the rule.
46		// the body looks like this:
47		// NFunction'Numberize(old'name(arg'list))
48		*/
49			NFunction'Numberize(UnList({Atom("@"), old'name, arg'list}));
50			// cannot use bare '@' b/c get a syntax error
51
52];
53
54// this function is local to NFunction.
55// special handling for numerical errors: return Undefined unless given a number.
5610 # NFunction'Numberize(x_IsNumber) <-- x;
5720 # NFunction'Numberize(x_IsAtom) <-- Undefined;
58// do nothing unless given an atom
59
60];	// LocalSymbols()
61
62