Housekeeping On Thursday there will be a quiz on Chapter 1. It will be weighted towards lists and tuples, but I can ask about pretty much anything we have done. There will be no Chapter 1 material on this quiz.
Recursion and the Call Stack (this and next time)
Learn the facts of life about return statements.
Are you confused about Return vs. Print?
There are two principal blocks of memory in a program. This is a very prudent investment of your time. These diagrams are extremely useful. You will see Kris using type hinting.
- Heap This is your program's data warehouse. All objects are created and stored here. Certain small items, such as small integers and one-character strings, are pre-slotted into the heap when the program starts. The garbage collector monitors the heap and deallocates memory for unused objects. If the heap runs low on memory, it can request more from the OS.
- Stack This is the portion of memory that manages all function calls. When a program starts up, the global frame is placed on the stack. When a function is called, a stack frame is put on top (pushed onto) the stack. When a function returns, its stack frame is abandoned and can be overwritten.
What's in a stack frame? The stack frame stores a return address so that when it returns, the caller resumes execution right where it left off. It also stores the parameters and local variables. Because a stack frame is abandoned when its function returns, all local variables die on return.
Parameters vs. Arguments Consider this program.
def square(x):
return x*x
print(square(4 + 7))
The value 4 + 7
inside of the call to square
in the main routine is an argument to the function. Arguments
can be expressions. When a function is called, all arguments are evaluated.
Since 4 + 7 = 11, the function square
will receive this value
and bind it to x
. To see this, let's do some spying.
def square(x):
print(f"Right after square begins: {locals()}")
return x*x
print(square(4 + 7))
We see that we have the parameter x → 11
in the
local symbol table for square
.
So, all arguments are evaluated prior to being passed to the function. What is actually stored on the stack it the heap address of the value that is the result evaluating the argument's expression. If the argument is just a variable, then a copy of the heap address of the variable's object is sent to the function being called.
A List Mystery: Dangers of Mutability
A Reprise: Aliasing
Copying a list