# Iteration - Mon, Sep 9

## Return

A return statement completed the evaluation of a call expression and provides its value:

• *`f(x)` for user-defined function `f`: switch to a new environment; execute `f`'s body
• `return` statement within `f`: switch back to the previous environment; `f(x)` now has a value

Only one return statement is ever executed in the body of a function. Here's a simple example:

``````def end(n, d):
"""Print the final digits of N in reverse order until D is found.

>>> end(34567, 5)
7
6
5
"""
while n > 0:
last, n = n % 10, n // 10
print(last)
if d == last:
return None``````

A slightly more evolved example:

``````def square(x):
return x * x

def search(f):
x = 0
while True:
if f(x):
return x
x = x + 1

def is_three(x):
return x == 3``````

An even more evolved example:

``````def inverse(f):
"""Find a functiong such that g(f(x)) --> x."""
return lambda y: search(lambda x: f(x) == y)``````

## Self-Referencing

An example of returning a function using its own name:

``````def print_sums(n):
print(n)
def next_sum(k):
return print_sums(n + k)
return next_sum``````

## If Statements and Call Expressions

Execution Rule for Conditional Statements: 1. Evaluate the header's expression (if present). 2. If it is a true value (or an else header), execute the suite & skip the remaining clauses.

Evaluation Rule for Call Expressions: 1. Evaluate the operator and then the operand subexpressions. 2. Apply the function that is the value of the operator to the arguments that are the values of the operands.

Here's an example of taking the real square root of a number `x`.

``````def real_sqrt(x):
if x > 0:
return sqrt(x)
else:
return 0.0``````

However, the following does not work with negative `x` values.

``````def if_(c, t, f):
if c:
return t
else:
return f

def real_sqrt(x):
return if_(x > 0, sqrt(x), 0.0)``````

As a regular if-else clause, this works just fine. However, when you call `if_`, it never actually gets called. As you call the function, the operands are evaluated, including `sqrt(x)`. If `x` is negative, the very function call causes an error as `sqrt(x)` is evaluated regardless.

## Logical Operators

To evaluate the expression `<left> and <right>`: 1. Evaluate `<left>`. 2. If the result is a false value `v`, then the expression evaluates to `v`. 3. Otherwise, the expression evaluates to the value of `<right>`.

To evaluate the expression `<left> or <right>`: 1. Evaluate `<left>`. 2. If the result is a true value `v`, then the expression evaluates to `v`. 3. Otherwise, the expression evaluates to the value of `<right>`.