remvalue, was: Strange plot2d behaviour (correction)



Richard Fateman wrote:
>  
> 1. It could be that subvar has a bug in it, at least relative to what you
> want. It is defined as...
>
> (defmspec $subvar (l) (setq l (cdr l))
> 	  (if (null l) (wna-err '$subvar)) (meval (cons '(mqapply array)
> l)))
>
> What you want is to evaluate s exactly once to get t, not twice to get 1.
> Why your function should evaluate s twice, I don't know. For example,
> h(s,t):=s+t  returns h(t,1) = t+1,  not 2.
>
>
> (defmspec $subvar (l) (setq l (cdr l))
> 	  (if (null l) (wna-err '$subvar))  (cons '(mqapply array) l))
>
> Note the problem is that subvar does an extra "ev" by calling meval. This is
> bringing the chickens home to roost: blaming ev.
>
> I'm not sure when subvar is supposed to be used. I've never seen it before
> this discussion.
>   
I thought subvar is synonymous to arrayapply but it seems it is not.
arrayapply works
correctly.
> It could be that the issue you are most concerned with is scope, and this ev
> is just a distraction.
>
> Consider
>
>
> t[1]:hello;
> h(s,t):=subvar(s,t);
> h(t,1);   
>    do you want t[1] or hello?
>   
I think I want hello. Since if we sanitize h:
h(uniq1,uniq2):=subvar(uniq1,uniq2)
then maxima returns hello.
> If you want hello, then the argument binding convention for maxima (and for
> lisp in 1969) of dynamic scope, is not going to get that answer.
>
> Rewriting maxima to do lexical scope, as is used in common lisp, might be
> worthwhile, and could be done by changing meval and associated programs,
> mostly in one source file, but could break user programs that now work.  I
> believe that Maple changed its scope rules about 10 years ago.
>
>
> Regarding replacing arguments with gensyms...
>
> Here is a program:
>
> sanitize(f):=block([subl:[], 
>                     s:apply(fundef,[f])],
>    subl:map(lambda([r],r=?gensym()),substpart("[",part(s,1),0)),
>    apply(define, [subst(subl,part(s,1)),
>                  subst(subl,part(s,2)) ]))
>
>
> Here is another program that is often equivalent:
>
> sanitize2(s):=( s:apply(fundef,[s]),
>   ev(subst(map(lambda([r],r=?gensym()),substpart("[",part(s,1),0)),s)))
>
> The sanitize program does not have to be sanitized, ever, because it doesn't
> use ev.
>
> The sanitize2 program uses ev, and I do not entirely trust it. Even if run
> through sanitize.
>   
Thank you very much!  See my other mail for a report on these functions.

> Also, if you insist on using ev inside your program, then I suspect that
> internal lambda-bindings or local bindings also need to be sanitized, and
> neither of these programs may be good enough. But I'm not usre.
>
> Regarding the case of 
>
> f(x):=block([y],y)
>
> consider even more...
> g(a):=lambda([x],a+x)$  /* g returns not a symbol, but a function with a
> local binding for the variable "a" */
>   

>
> add3:''g(3);   /* should be lambda([x],3+x) */
>
> add3(4)  -->  should be 7, but is a+4.
>   
I did this example. I agree this looks rather bad for maxima!  Luckily
this fails so badly that
people will not be tempted to use it. Something that does not work at
all is better than something
that is subtly broken.
> The equivalent lisp program gives 7.
>  (defun g(a)(lambda(x)(+ a x)))
>   (apply (r 3) '(4))
>
> This case of a returned functional argument has been discussed at length in
> the lisp literature, going back 40 years. It is a powerful concept missing
> from most other languages, even today.
>
>
>   
These are also called closures isn't it? They exist  in python:
 def adda(a):
    return(lambda x: x+a)

add3=adda(3)
add3(5)
   8

Michel