Problems with EV (WAS: Error message: Too many contexts)
Subject: Problems with EV (WAS: Error message: Too many contexts)
From: Stavros Macrakis
Date: Wed, 2 May 2007 13:42:06 -0400
On 5/2/07, Robert Dodier <robert.dodier at gmail.com> wrote:
>
> For some reason ev comes in for a lot of criticism.
> I don't think that is warranted; certainly not in this case.
>
Ev packages of a lot of miscellaneous functionality into simple syntax for
easy access on the command line. In that context, it is not too bad, because
it is an interactive environment and you can quickly see if you got things
wrong.
However, "ev comes in for a lot of criticism" for many good reasons...
especially when it is used programmatically:
1) Its semantics are very complicated. I challenge anyone to describe them
simply and abstractly. It is difficult to build solid programs on top of
quirky semantics.
2) It combines many functions which are only distantly related, if at all.
3) Its notation is inconsistent. Consider the simple notation
ev(<expr>,<symbol>). Depending on the symbol, it may mean:
apply the function <symbol> to <expr>: (x+1)^2,ratsimp
evaluate <expr> in a context where <symbol> is bound to True: asin(x),logarc
evaluate <expr> in a context where <symbol> and some related symbols are
bound to "sensible" values: detout
convert noun versions of <symbol> to verbs before evaluating <expr>:
'integrate(x,x),integrate
ignore <symbol>: 'factor(6),factor (cf. 'factor(6),nouns)
give an error: f:3 $ f(x):=x$ 'f(x),f
evaluate <symbol> and feed its value back to ev: q:[numer] $ 1/2,q
various special cases: pred, noeval, eval, ...
some quirky special cases: %e,numer => 2.718 seems OK, but compare to:
%e+1,numer => %e+1
block([numer:true],%e) => %e
ex: %e $ ex,numer => %e
4) Similar options operate differently.
sin(%pi),numer => 1.2e-16 OK
sin(float(%pi)) => 1.2e-16 OK
sin(%pi),bfloat => 0.0b0
sin(bfloat(%pi)) => 1.1b-17 Hmm
5) Without knowing the internals, it's hard to predict what it will do when
you combine options:
(x+1)^2,ratsimp,factor => (x+1)^2 OK, factor came last
(x+1)^2,factor,ratsimp => x^2+2*x+1 OK, ratsimp came last
but
sin(%pi),numer => 1.2e-16 OK
sin(%pi),bfloat => 0.0b0 OK
sin(%pi),numer,bfloat => 1.2b-16 OK, bfloat came last
sin(%pi),bfloat,numer => 1.2b-16 why not 0.0, since numer came last?
6) Its semantics are not compositional in the normal way.
ev( ev( sin(%pi), bfloat) , numer) => 1.2b-16
but
qq: ev(sin(%pi),bfloat) $ ev(qq,numer) => 0.0
7) Its core functionality appears to be equivalent to Lisp's eval. But it is
treacherous when used for evaluation:
q1: 'q2$ q2: 'q3$
ev(q1) => q3 --- OK, just like eval
qq: 'q1 $ ev(qq) =>
ev( concat(q,1) ) => q1 --- eval would have given q2
8) It does bizarre and surprising things in some cases:
ev(qq:q1) => q2 OK
qq => q2 !!!
(I do know why it behaves these ways, but it still manages to surprise me
sometimes.)
Some of the problems with ev are not so much about ev itself, but about the
way it is (ab)used by users.
For example, sometimes ev is used instead of subst, e.g.
expr: p+1$
expr, p=3
This is fine on the command line, but in a program, it can be disastrous
because of variable capture; subst is a much better option.
Well, that is a sketch of some of the problems with EV.
-s