Programming in Maple
Roger Kraft Department of Mathematics, Computer Science, and Statistics Purdue University Calumet
roger@calumet.purdue.edu
2.5. A no evaluation rule
We have made the claim that Maple uses full evaluation most of the time. You may have noticed already one place where Maple does not use full evaluation. Suppose we let x represent 5.
Now let x represent 6.
Maple did not use full evaluation here. If it had, Maple would have tried to assign the value 6 to 5. Maple did not evaluate the x on the left hand side of the assignment operator.
So we can state another of Maple's evaluation rules. The name on the left hand side of an assignment operator is not evaluated. Here is another example. Let us unassign y and then let x be a name for y .
Now consider the following assignment.
If Maple had evaluated the left hand side of the assignment operator, it would have assigned 5 to y . But it did not. The variable y is still unassigned.
Consider this example.
What should the next command do?
Maple used full evaluation on the right hand side of the assignment operator and no evaluation on the left hand side. Compare the last Maple command with the next one.
Now we can explain how "unassigning a variable" works. In the Maple command x:='x' the first x is not evaluated, since it is on the left hand side of the assignment operator. The second x is not evaluated either since the single quotes delay evaluation. So x gets assigned to it an unevaluated x , i.e., x is given itself as its value.
The assign command can be used to make the equal sign in Maple act like an assignment operator. So for example the following commands makes 2 the value of x .
Here is an example of a typical use of assign .
But it turns out that the assign command does not make an equals sign act exactly like an assignment operator. There is one important difference. The assign command uses full evaluation on both sides of the equal sign. Consider the following example.
Now let us investigate what the assign command did. First check the value of x .
It appears that assign did what we wanted. But if assign used full evaluation on both sides of the equals sign, then the x in x=23 should have evaluated to c and so the assign command should have assigned 23 to c and not x . Let us check the value of c .
Let us evaluate x to only one level.
Now we see that the assign command did not assign anything to x . It did assign 23 to c . (So why does x evaluate to 23?) So the assign command was not equivalent to the assignment statement x:=23 .
Here is one way to think about this last example. The assignment operator := was purposely chosen to be a non symmetric symbol to remind you that x:=y is not the same as y:=x (and y=:x is syntactically incorrect) and also to remind you that the assignment operator does not use the same evaluation rules on its left and right hand sides. On the other hand, the equals sign = is a symmetric symbol and, when interpreted as an equation, x=y is the same as y=x . Now assign(x=y) is not the same as assign(y=x) , but the assign command does use the same evaluation rule on both sides of the equals sign (i.e., full evaluation) so in that sense the = in an assign command is more symmetric than the := in an assignment statement.
Let us look at one last example of evaluation and the assignment operator. Give x the value 5.
What should the next statement mean?
If Maple had evaluated all of the x 's, it would have ended up trying to assign 7 to 5. But Maple only evaluated the x on the right of the assignment operator, so it assigned 7 to x .
Let us stop for a moment and compare the two Maple statements x:=5 and x:=x+2 with standard mathematical notation. The Maple command x:=5 translated into standard mathematical notation would become . What about x:=x+2 ? Should we translate it into ? But would be interpreted in standard mathematical notation as an equation that simplifies to which is not at all what we mean. Notice how the dual nature of the equals sign in standard mathematics is popping up again. The equals sign in is naturally taken as an assignment, but the equals sign in is naturally taken as part of an equation. So how should we express x:=x+2 in mathematical notation? In fact, there is no standard mathematical notation that would mean let have the value that is 2 more than what currently has (notice that just saying is not really the same thing). Without an explicit and unambiguous assignment statement, it is hard to express this idea.
But Maple can have its own problems with x:=x+2 . Even to Maple there is something a bit strange about this command. For example, suppose we unassign x .
Now tell Maple that x:=x+2 . What should this mean? Stop and think about it before executing the command.
Error, recursive assignment
Maple gave us an error message. For some reason, Maple does not like the last assignment statement. Let us see if the assignment even took place.
So in fact Maple did not even make the assignment. Here is why. There is really no problem with the above assignment but if Maple had made the assignment, then there would be a problem with trying to evaluate x . Let us suppose that Maple executed the last assignment statement. To execute the assignment x:=x+2 , Maple would need to evaluate the right hand side (but not the left hand side). If Maple had evaluated x+2 , it would see that, at that point, x does not have a value, so it would stop evaluating x+2 and it would assign x+2 as the value for x . Now suppose that in a separate command we would ask Maple to evaluate x . This is where there would be a problem. When Maple would try to evaluate x it would see that the value of x is x+2 and so it would replace x with x+2 . But then, because of the rule of full evaluation, Maple would need to evaluate x again. When Maple would evaluate x again it would get x+2 for x , and so it would plug this into x+2 to get (x+2)+2 . But then full evaluation would once again require that x be evaluated which would lead to ((x+2)+2)+2 . A little bit of thought shows that this would go on for ever. So if Maple performed the above "recursive assignment" and then tried to evaluate x , then Maple would get stuck trying to evaluate x an infinite number of times. So in order to avoid this kind of problem, Maple just refuses to perform the recursive assignment.
So if x has a value, then x:=x+2 is OK. But if x does not have a value, then x:=x+2 is a recursive assignment, which is not good. There are actually many ways to get a recursive assignment. Here is another.
Notice that it was not obvious from the command x:=y+2 by itself that this was a recursive assignment.
Maple cannot always detect a recursive assignment. Here is an example that comes up later in this chapter.
It may not be clear to you yet, but this was a recursive assignment. Here is what happens when we try to have Maple evaluate x0 .
Error, too many levels of recursion
If you should ever accidentally get a recursively defined name, just unassign the name you were using and then choose a different name.
Now x0 is no longer a recursivly defined name.
We will return to the idea of "recursion" when we get to the chapter on Maple programing. We will see that the idea of something referring to itself (i.e., recursion) is an important part of how Maple works, and it is important to computer science in general.