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