[an error occurred while processing this directive]
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))
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:
__________________
def primitivePlus (operands):
if (len(operands) == 0):
return 0
else:
return operands[0] + primitivePlus (operands[1:])
def initializeGlobalEnvironment():
...
globalEnvironment.addVariable('+', primitivePlus)
...
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
class Environment:
def __init__(self, parent):
self._parent = parent
self._frame = { }
def addVariable(self, name, value):
# 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)
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)):
newenv.addVariable(params[i], operands[i])
return _______________________
else:
evalError("Application of non-procedure: %s" % (proc))
Lazy Evaluation
What are the advantages of lazy evaluation?
What are the disadvantages of lazy evaluation?
Give an example of an expression that evaluates with both eager and lazy
evaluation, but takes much longer to evaluate with eager evaluation.
What expressions take longer to evaluate with lazy
evaluation than with eager evaluation?
class Thunk:
def __init__(self, expr, env):
self._expr = expr
self._env = env
self._evaluated = False
def value(self):
if not self._evaluated:
self._value = forceeval(self._expr, self._env)
self._evaluated = True
return self._value
def forceeval(expr, env):
value = meval(expr, env)
if isinstance(value, Thunk):
return value.value()
else:
return value
Eager Application Rule
def evalApplication(expr, env):
subexprvals = map (lambda sexpr: meval(sexpr, env), expr)
return mapply(subexprvals[0], subexprvals[1:])
Lazy Application Rule
def evalApplication(expr, env):
ops = map (lambda sexpr: _______________________, expr[1:])
return mapply(_________(expr[0], env), ops)
Like most of my generation, I was brought up on the saying: 'Satan finds
some mischief for idle hands to do.' Being a highly virtuous child, I
believed all that I was told, and acquired a conscience which has kept
me working hard down to the present moment. But although my conscience
has controlled my actions, my opinions have undergone a revolution. I
think that there is far too much work done in the world, that immense
harm is caused by the belief that work is virtuous, and that what needs
to be preached in modern industrial countries is quite different from
what always has been preached. Everyone knows the story of the traveler
in Naples who saw twelve beggars lying in the sun (it was before the
days of Mussolini), and offered a lira to the laziest of them. Eleven of
them jumped up to claim it, so he gave it to the twelfth. this traveler
was on the right lines. But in countries which do not enjoy
Mediterranean sunshine idleness is more difficult, and a great public
propaganda will be required to inaugurate it. I hope that, after reading
the following pages, the leaders of the YMCA will start a campaign to
induce good young men to do nothing. If so, I shall not have lived in
vain. ...
All this is only preliminary. I want to say, in all seriousness, that a
great deal of harm is being done in the modern world by belief in the
virtuousness of work, and that the road to happiness and prosperity lies
in an organized diminution of work.
First of all: what is work? Work is of two kinds: first, altering the
position of matter at or near the earth's surface relatively to other
such matter; second, telling other people to do so. The first kind is
unpleasant and ill paid; the second is pleasant and highly paid. The
second kind is capable of indefinite extension: there are not only those
who give orders, but those who give advice as to what orders should be
given. Usually two opposite kinds of advice are given simultaneously by
two organized bodies of men; this is called politics.
From In Praise of
Idleness, by Bertrand Russell (co-author of Principia
Mathematica), 1932
[an error occurred while processing this directive]