"subsop" in "procedure" cannot work, weird!

HI, all,

I found a weird problem:

When I used the subsop separately, it work fine. But when it was put in a procedure, then it cannot work. So weird!

For example:

>L:=[x,y,z,d];

                            L:=[x,y,z,d]

>L:=subsop(1=NULL,L);

                           L:=[y,z,d]

>L:=subsop(1=NULL,L);

                           L:=[z,d]

>L:=subsop(1=NULL,L);

                           L:=[d]

 

However, when I put the subsop in a procedure, it cannot work:

>F:=proc(L)

>L:=subsop(1=NULL,L);

>end proc;

>L:=[x,y,z,d];

                    L:=[x,y,z,d]

>F(L);

Error, (in F)illegal use of a formal parameter

----------------------------------------------------------------

 

Many thanks.

assignment

It would be the same error with:

F:=proc(L)
L:=1:
end proc;

Without the assignment it works:

F:=proc(L)
subsop(1=NULL,L);
end proc;

L:=[x,y,z,d];
F(L);
                              [y, z, d]
acer's picture

with side effects

If you really, really want to,

> F:=proc(L::evaln)
>   L:=subsop(1=NULL,eval(L));
> end proc:

> L:=[x,y,z,d];
                               L := [x, y, z, d]
 
> F(L);
                                   [y, z, d]
 
> F(L);
                                    [z, d]
 
> F(L);
                                      [d]
 
> F(L);
                                      []

Alternatively,

> restart:

> F:=proc(L)
>   L:=subsop(1=NULL,eval(L));
> end proc:

> L:=[x,y,z,d];
                               L := [x, y, z, d]
 
> F('L');
                                   [y, z, d]
 
> F('L');
                                    [z, d]
 
> F('L');
                                      [d]
 
> F('L');
                                      []

Some people think that this sort of thing is evil.

acer

Thanks, acer, I find another

Thanks, acer,

I find another way to solve this problem. here is the way:

> F:=proc(L)

>local LL;

>   LL:=subsop(1=NULL,LL);

>L:=LL;
> end proc:

> L:=[x,y,z,d];
                               L := [x, y, z, d]

>L:= F(L);
                                   [y, z, d]
 >L:= F(L);
                                    [z, d]
 >L:= F(L);
                                      [d]
 >F(L);
                                      []
 

By the way, shy it is evil? if I want to such thing, whether there are other methods that are not evil:)

Robert Israel's picture

Not that way

What you wrote won't work at all.  Perhaps you meant something like

> F := proc(L) subsop(1=NULL, L) end proc;

  L := [x,y,z,d];
  L := F(L);

etc.

 

acer's picture

simpler

I would probably do it like this,

> F:=proc(L)
>   subsop(1=NULL,L);
> end proc:
> L:=[x,y,z,d];
                               L := [x, y, z, d]
 
> L:= F(L);
                                L := [y, z, d]
 
> L:= F(L);
                                  L := [z, d]
 
> L:= F(L);
                                   L := [d]
 
> L:= F(L);
                                    L := []

That keeps it as simple as possible, is easiest to understand, and is less confusing.

Doing it the other way, to bring about the change in L as a so-called side-effect on the name, can cause confusion. In a sense, it's deliberately subverting any protection Maple may otherwise give you about not having your procedure overwrite the formal parameter. As a general rule, you may not wish to do that unless it's necessary. For your example, the above way to overwrite L (explicitly, by the call to the proc) is more straightforward.

Way back in the day, before Maple allowed multiple assignments, some routines would use side-effects as a mechanism to fake multiple assignment. For example,

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(x,'y'):
> x,y;
                                    33, 22
 
> x := f(x,'y'):
> x,y;
                                    99, 66

The above procedure changes both x and y. There was a time, long ago, when that was one of the easier ways to do get that effect. Nowadays, it can be done much more simply with a multiple assignment,

> restart:

> f := proc(a)
>  3*a, 2*a;
> end proc:

> x:=11:

> x,y := f(x);
                                x, y := 33, 22
 
> x,y := f(x);
                                x, y := 99, 66

When using side effects, one can get confused the by quotes, by either forgetting them or inserting them when they are not wanted.

> restart:

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(11,y): # it works once, without quotes...
> x,y;
                                    33, 22
 
> x := f(11,y): # and now, the second time...
Error, (in f) illegal use of a formal parameter

And, doing it another way,

> f := proc(x::evaln)
>   x := 2*eval(x);
> end proc:

> x:=11:

> f(x):
> x;
                                      22
 
> f('x'):
Error, illegal use of an object as a name

And also, documenting its use for others is more involved if it's implemented in these ways.

acer

I agree

This simpler form is what I have shown above. I also dislike side effects. In fact, I think that the Maple library should be updated in this regard.

to acer: Yes, it is

to acer:

Yes, it is great.

Thanks so much.

to  Robert Israel: yes,

to  Robert Israel:

yes, when you want to newline, shift+enter instead of enter can get:

> F:=proc(L)

>local LL;

>  LL:=subsop(1=NULL,LL);
> end proc:

> L:=[x,y,z,d];
                               L := [x, y, z, d]

>L:= F(L);
                                   [y, z, d]
 >L:= F(L);
                                    [z, d]
 >L:= F(L);
                                      [d]
 >F(L);
                                      []
 

actually, it is the same as:

F := proc(L) local LL; LL:=subsop(1=NULL,LL);(wihtout "enter")end proc;

 

Robert Israel's picture

Not about enter

That wasn't my point at all.  Whether on one line or several, your code

> F := proc(L) local LL; LL:=subsop(1=NULL,LL); end proc;

will not work.  The result of F(anything) is just NULL.  Note that you haven't used L at all in the procedure.

The version you had before

> F:=proc(L)
>local LL;
>   LL:=subsop(1=NULL,LL);
>L:=LL;
> end proc:

won't work either, because the additional statement L := LL will generate an error " illegal use of a formal parameter".

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}