Your solution probably doesn't work because
the "wart" can be undone. The macsyma variable
x is $x in lisp
?x is x in lisp.
So you have access.
There is a deep issue of separating indeterminates
in your expressions from program variables in your
programs. Because this so often doesn't matter,
most people (and systems) don't make the appropriate
separation. Either z is an indeterminate in
which case it makes sense to compute diff (...,z)
or z is a place to store a value, like 43.
Allowing both is hazardous, and especially
hazardous when the value of z could be an expression
involving other symbols.
Another issue is "what environment does EV use" and
that can be resolved in several ways, officially by
using lexical or dynamic binding. Macsyma, along with
its original host Lisp system, uses dynamic binding, a
system that works pretty well for interactive programming
but has problems with building of large static programs.
Using warts helps. Lexical scope, used by Common Lisp
and Scheme also helps.
But the immediate problem you have is caused by using EV.
try this:
z:z^8;
ev(z);
ev(ev(z));
Here's a suggestion: Never use ev for replacing
a variable by its value. Use subst. In fact, keeping
x_the_indeterminate entirely separate from
x_the_box_holding_some_value, and only occasionally
doing subst(value, x, expression) will remove many
sources of confusion and error.
If you can't use subst, consider using ev.
(This, incidentally, suggests that the prominent
usage of ev in the draft macsyma manual should be
reconsidered.)
willisb@unk.edu wrote:
>
> Awhile back we had some discussion of the merits of writing
> packages for Maxima in Lisp or in Maxima. I claim that coding
> in Lisp is the best way to avoid name clashes that can plague
> Maxima functions that take an argument that is a Maxima
> expression. To illustrate:
>
> Consider the function G defined in Maxima as
>
> (C2) G(e,x) := block([z],
> z : diff(e,x),
> ev(z * e, ratsimp));
> (D2) G(e,x):=BLOCK([z],z:DIFF(e,x),EV(z*e,RATSIMP))
>
> Although we declared z to be a local variable, if e depends
> on z, we probably don't get what we want:
>
> (C3) G(x*a^8,x);
> (D3) a^16*x /* this is what we want */
>
> (C4) G(x*z^8,x);
> (D4) x*z^128 /* yikes! this isn't what we want. */
>
> Maxima isn't misbehaving; we have a name clash. We can
> avoid the problem by putting a "wart" on the local variable.
> For example
>
> (C5) H(e,x) := block([%z],
> %z : diff(e,x),
> ev(%z * e, ratsimp));
> (D5) H(e,x):=BLOCK([%z],%z:DIFF(e,x),EV(%z*e,RATSIMP))
>
> Now we can have e depend on z and H does what we want:
>
> (C6) H(x*a^8,x);
> (D6) a^16*x
> (C7) H(x*z^8,x);
> (D7) x*z^16
>
> Should anyone use a variable %z, we're back to the same problem:
>
> (C8) H(x*%z^8,x);
> (D8) %z^128*x
>
> We could tell users not to use warted variables, but as far as
> I know, Maxima has no such prohibition. Some commercial Macsyma
> code has warted variables (look at the specfun.macsyma code).
>
> I claim that a better way to avoid name clashes is to code in Lisp.
> Defining f as
>
> (defun $f (e x)
> (let ((z ($diff e x)))
> (mfuncall '$ev (mul* e z) '$ratsimp)))
>
> we don't have a name clash because of the way Maxima "dollarifies"
> Maxima variables. Thus
>
> (C10) F(x*a^8,x);
> (D10) a^16*x
> (C11) F(x*z^8,x);
> (D11) x*z^16
> (C12) F(x*%z^8,x);
> (D12) %z^16*x
>
> At least, this is how I see it; spending several evenings with
> a good Common Lisp book was the best thing I did for my
> Maxima competence.
>
> How do the other M's avoid name clashes?
>
> Barton
>
> _______________________________________________
> Maxima mailing list
> Maxima@www.math.utexas.edu
> http://www.math.utexas.edu/mailman/listinfo/maxima