ML Lecture 4
Continuing functions, function calling, and lifetime of identifiers
Identifier Scopes and Lifetimes
- When an identifier is created and assigned a value to refer to using
the val command, it has a certain area of use and a certain lifetime.
This area is called its scope.
- If we just type in a val statement into ML, that identifier-value
binding has a scope of the rest of the ML session, or until the
identifier is reassigned a different value.
- A parameter of a function has a scope that is just the body of the
function. Its lifetime is just one execution of the function body.
The ML stack of identifiers (and function names)
- Think of an upward growing stack of identifier-value bindings. Each
val statement adds a layer onto this stack.
- A reassignment of an existing identifier does not erase the old one.
It simply adds a new layer to the stack.
- When an indentifier is used in an expression, the stack is searched
from top to bottom. The first occurrence of the identifier is the
one whose value is used in the expression.
- When a function is defined, its name and body is added to the stack
as well. Very importantly, any identifier that is in the body that is not
a parameter is immediately searched for on the stack and located. It
is this identifier-value binding that is used during function execution.
- Parameters are viewed as temporary additions to the identifier stack,
only there during the function execution. When the function begins (is
called), the value passed in as an argument is used to create an identifier-value
binding for that parameter. When the function ends, that entry in the identifier
stack is erased.
- Functions can themselves be redefined! Just like identifiers,
they are simply added to the stack, and the old versions are not removed.
Previously defined functions using that function name refer to the old
binding, because they looked it up immediately when they were defined.
In class, lots of examples, found here.