10. Execution model
How a Korrin program runs, once it has lexed, parsed, and resolved without error.
10.1 Program start
A program is a list of top-level statements. They execute in order, top to
bottom, in the global scope. fn and class statements bind their names
when reached, so a function must be defined above its first call at the top
level (though mutual recursion between functions works, because the calls happen
later, at run time).
fn even(n):
if n == 0:
return true
return odd(n - 1)
fn odd(n):
if n == 0:
return false
return even(n - 1)
print(even(10))
# => true
10.2 Scopes and environments
There are exactly two kinds of scope: the global scope, and a function-call
scope (ADR 0011). if, while,
and for do not create scopes. Each call gets a fresh scope whose parent is
the scope where the function was defined (not where it was called) — this is
what makes closures work.
Name resolution — for both reads and the target of = — searches the current
scope, then each enclosing scope, out to global. = updates the nearest binding
found, or creates one in the current scope if there is none.
10.3 Evaluation order
- Binary operators evaluate the left operand, then the right, then combine.
- A call evaluates the callee, then each argument left to right, then calls.
and/orevaluate the left operand, and the right only if needed.- List and map literals evaluate their elements in source order (for a map, each key before its value).
10.4 Value semantics
Scalars (nil, bool, int, float) and str are effectively immutable —
operations produce new values. list, map, and instance are reference
types: the same object can be reached through several names, and a mutation
through one is visible through all (§3.4).
A for loop iterates over a snapshot of a list taken when the loop starts,
so appending to the list inside the loop does not extend the iteration.
xs = [1, 2, 3]
for x in xs:
xs.push(x)
print(xs.len())
# => 6
10.5 Runtime limits
Function-call nesting is bounded. The interpreter grows its working stack on
demand, but a call depth beyond its limit (currently 10 000) is reported as
E0313 rather than aborting the process. This turns an infinite
recursion into a diagnostic.
10.6 Termination
A program ends when its last top-level statement finishes, or at the point a runtime error is raised. There is no explicit exit function in Milestone 1.