# Tail Calls - Wed, Nov 6

## Scope

The way in which names are looked up in Scheme and Python is called lexical scope (or static scope). You can see what names are in scope by inspecting the definition.

• Lexical Scope: The parent of a frame is the environment in which a procedure was defined.
• Dynamic Scope: The parent of a frame is the environment in which a procedure was called.
``````(define f (lambda (x) (+ x y)))
(define g (lambda (x y) (f (+ x x))))``````

What happens when you call `(g 3 7)`? The answer to this question depends on your scope:

• Lexical Scope: The parent for `f`'s frame is the global frame, which doesn't contain `y`.
• `Error: unknown identifier: y`
• Dynamic Scope: The parent for `f`'s frame is `g`'s frame.
• `13`

FOR PROJECT 4: Instead of just having `lambda` procedures, you'll need to implement `mu` procedures (a special form to create dynamically scoped procedures).

## Tail Recursion

### Functional Programming

• All functions are pure functions
• No re-assignment and no mutable data types
• Name-binding values are permanent

• The value of an expression is independent of the order in which sub-expressions are evaluated
• Sub-expressions can safely be evaluated in parallel or only on demand (lazily)
• Referential Transparency: The value of an expression does not change when we substitute one of its subexpressions with the value of that subexpression

No `for/while` statements! Can we make basic iteration efficient?

### Recursion and Iteration in Python

``````def factorial(n, k):
if n == 0:
return k
else:
return factorial(n-1, k*n)``````

The code block above runs in linear time and in linear space.

``````def factorial(n, k):
while n > 0:
n, k = n-1, k*n
return k``````

The code block above runs in linear time but in constant space.

## Tail Calls

A procedure call that has not yet returned is active. Some procedure calls are tail calls. A Scheme interpreter should support an unbounded number of active tail calls using only a constant amount of space.

A tail call is a call expression in a tail context:

• The last body sub-expression in a `lambda` expression (or procedure definition)
• Sub-expressions 2 & 3 in a tail context `if` expression
• All non-predicate sub-expressions in a tail context `cond`
• The last sub-expression in a tail context `and`, `or`, `begin`, or `let`