When I was studying the SICP course, the execution order of the following code in the environment diagram is inconsistent with what I expected.
def add_one(x):
y = x+1
return y
def square(x):
return x*x
square(add_one(9))
I am expecting the following evaluation order:
- Evaluate the operator
square. A function value is returned. - Evaluate the operand. Now we have to evaluate another expression
add_one(9). - Evaluate the operator
add_one. A function value is returned. - Evaluate the operand
9. Now the expressionadd_one(9)returns 10 - The whole expression
square(add_one(9))return 100.
However, I run the code on this website It told me that the add_one frame created before the square, which is opposite of what I expected. Is it right?
I asked ChatGPT about this question. It gives the answer that this is because in Python, the priority of function calls is higher than that of operators.
Your order is evaluation is mostly correct. However you are confusing "creation of the frame" with "evaluation of the frame".
To call a function, Python evaluates the function and its arguments. This order appears to be left-to-right, but I cannot find anything in the documentation that guarantees this. [Other StackOverflow answers say it is guaranteed left-to-right, so maybe there's something I'm missing.]
Only after the function and its arguments are evaluated is the function call actually made. This is when the frame is created.
Try the following code. It will give you a clearer idea of evaluation order.
Obviously, in most cases, the evaluation of a function is a simple name lookup. But in cases where evaluation of the function is not trivial, you can see that this evaluation happens before the arguments are evaluated.