One-Slide Summary • A type is a (possibly infinite) set of values. Each type supports a set of valid operations . Types can be latent or manifest, static or dynamic, strong or weak. • We can change the Charme interpreter to support manifest (program visible) types. • A network is a group of three or more communicating entities. Types & • Bandwidth is the throughput of a communication resource, Types & measured in bits per second. Latency is the time delay between the moment when communication is initiated and Networking Networking the moment the first bit arrives, measured in seconds. • In circuit switching , a path through a network is reserved (high quality-of-service, used in telephones). In packet switching , each packet is routed individually (internet, postal service). #2 Administrivia Outline • Start PS8 and PS9 Now – PS9 Team Requests due Mon Nov 15 • Administration – PS9 Project Descriptions due Wed Nov 17 • StaticCharme Typechecking – PS9 Design Review Signup Wed Nov 17 (Class) • Networking History – PS9 Presentation Requests Mon Dec 6 • Latency, Bandwidth, Switching • PS9 Final Project Presentation Wed Dec 8 • The Internet – or • Dynamic Web Sites • PS9 Final Project Report Tue Dec 14 #3 #4 Displeased Pleased • 6x Difficulty • 4x Nothing really • 7x Broad, useful, realistic topics • 4x Time consuming • 6x Professor • 2x Can't figure it out on my own • 5x Thinking and concepts, not just rote coding • 2x Dislike Scheme • 4x Challenging • 2x Dislike Python • 3x Think in a new way • 2x Book is hard to read and disorganized • 3x Liberal arts ties • Course moves fast • 3x Godel lectures • Large frameworks of existing code • 2x TA quality • Disheartening that others find it easy while I struggle • Reading quizzes served no purpose • 2x Fun problem sets (e.g., games, fractals) • Open-ended problem sets (I'm not creative) • 2x Candy and/or trivia • “One answer per day” rule • 2x Other • Myself for not putting in more effort • Learning multiple languages • Godel's proof • Many office hours • Many hours on HW + Reading, poor Exam grade #5 #6
Types of Types Recall the Goal • Given a Charme program somewhat like this: StaticCharme Charme (define square : number -> number (lambda (x : number ) (* x x))) Manifest Latent (square 3) change grammar, represent types (square “hello”) • The static type annotations are in red . Statically Checked Dynamically Checked • The second application (square “hello”) has a type error. typecheck expressions before eval – You can't multiply hello by hello, unless you're the Beatles. #7 #8 Static Type Checking Adding Type Checking def typecheck(expr, env): if isPrimitive(expr): def evalLoop(): return typePrimitive(expr) initializeGlobalEnvironment() elif isConditional(expr): while True: return typeConditional(expr, env) ... elif isLambda(expr): for expr in exprs: return typeLambda(expr, env) typ = typecheck(expr, globalEnvironment) elif isDefinition(expr): if typ and typ.isError(): typeDefinition(expr, env) print "Type error:" + typ.getMessage() elif isName(expr): else: return typeName(expr, env) res = meval(expr, globalEnvironment) elif isApplication(expr): if res != None: return typeApplication(expr, env) print str(res) else: evalError ("Unknown expression: " + str(expr)) #9 #10 class Environment: # Store a [type, value] pair for each variable. Typechecking Names ... def addVariable(self, name, typ, value): self._frame[name] = (typ, value) def lookupPlace(self, name): def typeName(expr, env): if self._frame.has_key(name): return self._frame[name] return env.lookupVariableType(expr) elif (self._parent): return self._parent.lookupPlace(name) else : return None def lookupVariableType(self, name): place = self.lookupPlace(name) def evalDefinition(expr, env): if place: return place[0] name = expr[1] else: return CErrorType("Name not found") value = meval(expr[4], env) def lookupVariable(self, name): typ = CType.fromParsed(expr[3]) return self.lookupPlace(name)[1] env.addVariable(name, typ, value) ... #11 #12
Static Type Checking def typeDefinition(expr, env): assert isDefinition(expr) def typecheck(expr, env): if len(expr) != 5: if isPrimitive(expr): evalError ("Bad definition: %s" % str(expr)) return typePrimitive(expr) name = expr[1] elif isConditional(expr): if isinstance(name, str): return typeConditional(expr, env) if expr[2] != ':': elif isLambda(expr): evalError ("Definition missing type: %s" % str(expr)) return typeLambda(expr, env) typ = CType.fromParsed(expr[3]) elif isDefinition(expr): etyp = typecheck(expr[4], env) typeDefinition(expr, env) if not typ.matches(etyp): elif isName(expr): evalError("Mistyped definition: ..." % (name, typ, etyp)) return typeName(expr, env) elif isinstance(name, list): elif isApplication(expr): evalError ("Procedure definition syntax not implemented") return typeApplication(expr, env) else: evalError ("Bad definition: %s" % str(expr)) else: evalError ("Unknown expression: " + str(expr)) Example: (define x : Number “hello”) Example: (define y : Number (+ 2 3)) #13 #14 Static Type Checking class Procedure: def __init__(self, params, typ, body, env): self._params = params def typecheck(expr, env): self._body = body if isPrimitive(expr): self._typ = typ return typePrimitive(expr) self._env = env elif isConditional(expr): Add type to def getParams(self): return typeConditional(expr, env) Procedure return self._params elif isLambda(expr): def getParamTypes(self): return typeLambda(expr, env) return self._typ elif isDefinition(expr): (define square : (Number -> Number) def getBody(self): return self._body typeDefinition(expr, env) (lambda (x : Number) (* x x))) def getEnvironment(self): return self._env elif isName(expr): def __str__(self): return typeName(expr, env) return "<Procedure %s / %s>" \ elif isApplication(expr): % (str(self._params), str(self._body)) return typeApplication(expr, env) else: evalError ("Unknown expression: " + str(expr)) #15 #16 def typeLambda(expr, env): assert isLambda(expr) def evalLambda(expr, env): if len(expr) != 3: evalError ("Bad lambda expression: %s" % str(expr)) assert isLambda(expr) # this is a bit tricky - we need to "partially" apply it if len(expr) != 3: # to find the type of the body evalError ("Bad lambda expression: %s" % (str(expr))) newenv = Environment(env) params = expr[1] params = expr[1] paramnames = [] paramtypes = [] Study me paramtypes = [] paramnames = [] assert len(params) % 3 == 0 for Exam 2! assert len(params) % 3 == 0 for i in range(0, len(params) / 3): for i in range(0, len(params) / 3): (lambda (x : Number name = params[i*3] name = params[i*3] y : Number) assert params[(i*3)+1] == ':' (* x y)) typ = CType.fromParsed(params[(i*3)+2]) assert params[(i*3)+1] == ':' paramnames.append(name) paramnames.append(name) paramtypes.append(typ) typ = CType.fromParsed(params[(i*3)+2]) newenv.addVariable(name, typ, None) paramtypes.append(typ) resulttype = typecheck(expr[2], newenv) return Procedure(paramnames, paramtypes, expr[2], env) return CProcedureType(CProductType(paramtypes), resulttype) #17 #18
Recommend
More recommend