Inconsistency when using previously defined variables as arguments to functions
Subject: Inconsistency when using previously defined variables as arguments to functions
From: Stavros Macrakis
Date: Mon, 31 Jan 2011 10:29:28 -0500
On Sun, Jan 30, 2011 at 23:55, Robert Dodier <robert.dodier at gmail.com>wrote:
> On 1/30/11, Stavros Macrakis <macrakis at alum.mit.edu> wrote:
>
> > * ev is a weird and complicated routine, and you should avoid using it
> > unless you absolutely have to.
>
> The problem with ev is that it's too complicated to be able to predict
> what's going to happen when it's called. I'm in favor of moving most
> of the 50 different things it does into separate functions.
>
The reason 'ev' is such a mess is that it is really a "do what I mean"
system designed so that the command-line syntax xxx, yyy will work
'intuitively'. I agree entirely that all its functions should be available
through clean, separate functions; and there are only a few functions that
are not already available that way. Most of the 50 things it does already
do exist as independent functions or global variable settings. One of the
nice things ev does for you is let you forget whether something is a
function or a global variable. For example ev(x,ratsimp) == ratsimp(x), but
ev(x,numer) == block([numer:true], x); and then there's ev(x,float) ==
block([float:true],x) which is NOT equivalent to float(x) :-( .
> That said, the function exists and it's documented, so we can hardly
> be surprised that people use it.
>
I agree. There should be a big WARNING at the top of the documentation.
> * ev( ... , simp ) is synonymous with ev( ... ) unless you have previously
> > set simp to false (which is a bad idea). What did you expect it to do?
>
> I disagree that simp:false is a bad idea. The effect is exactly what
> one would expect; it disables built-in simplifications. If that's what
> you want, then great.
>
Certainly, simp:false has its uses. But in this case, I very much doubt
that the user actually needed or wanted simp:false.
Maxima is kind of clumsy with simplification -- there really isn't any
> way to control built-in simplifications, short of disabling them
> entirely. That's a serious design flaw IMNSHO.
>
The simplest way to control built-in simplifications is judicious use of
box(). Beyond that, things get tricky. For example, the fact that "+" is
commutative and associative allows Maxima to have a standard order of
arguments, which simplifies and speeds up many algorithms. If I decided to
turn off the associativity of "+", many many things in Maxima would no
longer work -- not just in the simplification of "+", but any function which
assumes that constant arguments precede variable arguments, for example.
(That is not sloppy programming, but an explicit part of the 'contract' of
Maxima's internal representation.)
It is of course possible to imagine a system that works directly from the
axioms (which could be switched on and off), but I would think it would be
much slower and less powerful (because there are many non-trivial theorems
which the system would have to rederive). Another approach is what we
currently do with the "." operator, which has a large (and confusing) array
of switches; the main problem right now is that there is only one "."
operator, and no clear way to define the interactions between multiple
operators (say that operator *** is left-distributive over operator +++).
Perhaps that is one way forward.
What do you have in mind as a design?
-s