Fix the inefficient evaluation of translated predicates
[maxima.git] / demo / macex.dem
blob3e14b7f03acd47629d5c8a4896113d4505e470cd
1 /* ==================================================================== */
2 /* file: macex.dem     */
5 /* This is a demo of Macsyma's macroexpanding commands and the use of
6 the macroexpansion switch.  */
8 (showtime:all,macroexpansion:false)$
10 /* First we need a macro to play with.  Let's define a caseq statement
11 of the form:
13 caseq(<var>,[<keys1>],<stmt1>,
14             [<keys2>],<stmt2>,
15             ....,
16             [<keysn>],<stmtn>)
18 where the first <stmt> that has <var> as a member of the associated
19 <keys> is the one chosen to execute.  */
21 caseq(var,[pairs])::=
22      if length(pairs)<=2
23         then buildq([var,keys:first(pairs),statement:last(pairs)],
24                     if member(var,'keys) then statement)
25         else buildq([var,keys:first(pairs),
26                          statement:first(rest(pairs)),
27                          pairs:rest(rest(pairs))],
28                     if member(var,'keys) 
29                        then statement
30                        else caseq(var,splice(pairs)))$
32 /* let's use our caseq macro to define a simple predicate.  */
34 variablep(x)::=buildq([x],caseq(x,[a,b,c,d,e],true));
36 /* to make sure it works.  */
38 display(variablep(var1),variablep(var2)),var1:'a,var2:'z;
40 /* we can see what variablep is expanding into.  */
42 macroexpand(variablep(some_form));
44 /* we can also watch the expansion by stages.  */
46 macroexpand1(variablep(some_form));
48 macroexpand1(''%);
50 /* we might also create simple typep macro using caseq.  */
53 typep(x)::=buildq([x],caseq(x,[1,2,3,4,5,6,7,8,9,0], 'digit,
54                               [a,b,c,d,e,f,g,h,i,j], 'variable,
55                               ["+","-","*","/","^"], 'operator))$
57 /* let's see what things are expanding into.  */
59 macroexpand(typep(test));
61 /* the nested caseq doesn't expand because macroexpand and
62 macroexpand1 only look at the top level function.  to expand all
63 levels we can do:  */
65 scanmap('macroexpand,'(typep(test)));
67 /* let's test it just to make sure it works.  */
69 ev(%,test="*");
71 /* compare the time it just took to evaluate the macro when expanded
72 to the time it takes to expand it from scratch and then eval.  */
74 ev(typep(test),test="*");
76 /* this is why we can save time by using the macroexpansion switch.  */
78 form:'(typep(a));
80 ev(form);
82 macroexpansion:expand;
84 ev(form);
86 /* there's no savings on the first call after macroexpansion has been
87 reset, but there is on all subsequent calls.  */
89 ev(form);
91 /* macroexpand also uses the saved expansion. */
93 macroexpand(''form);
95 /* note that form still displays nicely.  */
97 form;
99 /* if we set macroexpansion to displace however, each macro call will
100 be completely replaced by the equivalent code.  */
102 (macroexpansion:displace,ev(form));
104 form;
106 /*  note that once the call is displaced, the original call cannot be
107 retrieved by resetting macroexpansion.  */
109 (macroexpansion:false,ev(form));
111 form;
113 showtime:false$