[an error occurred while processing this directive]

Class 20 Notes

Lecture Slides, Suitable For Printing

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():
   ...
   globalEnvironment.addVariable('+', primitivePlus)
   ...

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 = { }
    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)

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)):
            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]