[an error occurred while processing this directive]

## cs150: Notes 29

#### Assignments Due

• This week: read Chapter 12
• Someday this week, there may be a "surprise" quiz. Your quiz grade will be the maximum of your grades on the two quizzes. The "surprise" quiz will cover the readings from Neil de Grasse Tyson; Gödel, Escher, Bach; and the article on John Backus (from Notes 26).
• GEB reading (by Friday, 30 March): Aria with Diverse Variations and Chapter 13. Chapter 13 proves that the halting problem is not decidable, and introduces the Church-Turing Thesis (which we will explore more in later classes). You will not be assigned to read Chapter 14, but it goes into more depth on Gödel's proof and is highly recommended.
• Wednesday, 4 April: Last day to arrange an "extra ambitious" ps9 project that will replace ps8
• Friday, 6 April: Problem Set 7
• Monday, 9 April: Project teams and ideas for PS9
• Friday, 13 April: Problem Set 8 (out Friday, 6 April)
• Friday, 20 April: Exam 2 (out Monday, 16 April)
• Monday, 30 April: Project Presentations (Problem Set 9)
• Monday, 7 May: Last day to turn in Final Exam (out Monday, 30 April)

### Core Evaluator

```def meval(expr, env):
if isPrimitive(expr):
return evalPrimitive(expr)
elif isConditional(expr):
return evalConditional(expr, env)
elif isLambda(expr):
return evalLambda(expr, env)
elif isDefinition(expr):
evalDefinition(expr, env)
elif isName(expr):
return evalName(expr, env)
elif isApplication(expr):
return evalApplication(expr, env)
else:
evalError ("Unknown expression type: " + str(expr))
```

### Primitives

```def isNumber(expr):
return isinstance(expr, str) and expr.isdigit()

def isPrimitiveProcedure(expr):
return callable(expr)
```

```def isPrimitive(expr):
return (isNumber(expr) or isPrimitiveProcedure(expr))

def evalPrimitive(expr):
# A primitive evaluates to its pre-defined value
if isNumber(expr):
return int(expr)
else:

__________________
```

### Example Primitive Procedure

```def primitivePlus (operands):
if (len(operands) == 0):
return 0
else:
return operands[0] + primitivePlus (operands[1:])

def initializeGlobalEnvironment():
...
...
```

### Conditionals

```def isSpecialForm(expr, keyword):
return isinstance(expr, list) \
and len(expr) > 0 and expr[0] == keyword

def isConditional(expr):
return isSpecialForm(expr, 'cond')

def evalConditional(expr, env):
assert isConditional(expr)
if len(expr) <= 2:
evalError ("Bad conditional expression: %s" % str(expr))
for clause in expr[1:]:
if len(clause) != 2:
evalError ("Bad conditional clause: %s" % str(clause))
predicate = _____________

result = ____________________
if not result == False:

return _________________________

evalError ("No conditional predicate evaluates to non-false value: %s"
% (expr))
return None
```

### Environments, Definitions, and Names

```class Environment:
def __init__(self, parent):
self._parent = parent
self._frame = { }
# add a new name, or replace old value
self._frame[name] = value
def lookupVariable(self, name):
if self._frame.has_key(name):
return self._frame[name]

____________________:

return ____________________________
else:
evalError("Undefined name: %s" % (name))
def toString(self):
return "" % (str(self._frame), str(self._parent))

def isDefinition(expr):
return isSpecialForm(expr, 'define')

def evalDefinition(expr, env):
assert isDefinition(expr)
if len(expr) != 3:
evalError ("Bad definition: %s" % str(expr))
name = expr[1]
if isinstance(name, str):

_____________________________

_____________________________

elif isinstance(name, list):
evalError ("Procedure definition syntax not implemented")
else:
evalError ("Bad definition: %s" % str(expr))

def isName(expr):
return isinstance(expr, str)

def evalName(expr, env):
# To evaluate a name, lookup the value of the name in the environment
assert isName(expr)
return env.lookupVariable(expr)
```

#### Procedures and Applications

```
class Procedure:
def __init__(self, params, body, env):
self._params = params
self._body = body
self._env = env
def getParams(self):
return self._params
def getBody(self):
return self._body
def getEnvironment(self):
return self._env
def toString(self):
return "" % (str(self._params), str(self._body))

def isLambda(expr):
return isSpecialForm(expr, 'lambda')

def evalLambda(expr,env):
assert isLambda(expr)
if len(expr) != 3:
evalError ("Bad lambda expression: %s" % str(expr))

return __________________________

def isApplication(expr):
# Applications are lists [proc, oper, oper]
# Assumes expr is not a special form (must check special forms first)
return isinstance(expr, list)

def evalApplication(expr, env):
# To evaluate an application, evaluate all the subexpressions

subexprvals = map (____________________________, expr)

return mapply(________________, ________________)

def mapply(proc, operands):
if (isPrimitiveProcedure(proc)):
return ____________________
elif isinstance(proc, Procedure):
params = proc.getParams()

newenv = _____________________
if len(params) != len(operands):
evalError ("Parameter length mismatch: %s given operands %s" \
% (proc.toString(), str(operands)))
for i in range(0, len(params)):

return _______________________
else:
evalError("Application of non-procedure: %s" % (proc))

cs1120: Computer Science
University of Virginia

weimer@virginia.edu
Using these Materials

```