Com S 541 Lecture -*- Outline -*- * Extensions for a Practical Langauge (2.6-2.8) Q: Why not just program in the kernel language? Too verbose ** Syntactic conventions (2.6.1) ------------------------------------------ SYNTACTIC SUGARS FOR DECLARATIONS AND PATTERNS local X = E in S end ==> local X in X=E S end lit(f1:E1, ..., fn: En) ==> local X1 = E1 in ... local Xn = En in lit(f1:X1, ..., fn:Xn) end ... end local = in ==> local X1 ... Xn X0 in X0 = = X0 end ------------------------------------------ Q: Any conditions on the new variables in the last one? Q: How does this get back to kernel syntax? Q: Why do they preserve meaning? Q: What sugars would help with if and case statements? elseif, inStatement [], andthen Q: How could you desugar the short-curcuiting andthen and orelse? ------------------------------------------ NESTING MARKERS Use '$' to turn a statement into an expression Examples: {Obj get($)} ==> local X in {Obj get(X)} X end ------------------------------------------ Q: What's the general rule for this? ** Expressions and Functions (2.6.2) ------------------------------------------ EXPRESSIONS AND FUNCTIONS How to translate into kernel syntax: fun {Add1 X} X+3 end {Add1 3} {Add1 3 * 4} {Add1 {Add1 3 * 4}} ------------------------------------------ ** Interactive Interface (2.6.3) Q: How can you think of declare in terms of kernel syntax? like local, but it's open ended Q: Could you write a rule in the TTS for Oz for declare? Need a new system, since the interactive loop manipulates its environment. TTS for interactive State = (Statement)* x Environment x Store T = { (nil, E, s) | (nil, E, s) in State } input[[S]] = ([S], {}, {}) output[[(nil, E, s)]] = s Transitions ( -i-> ) (declare X | Rest, E, s) -i-> (Rest, E', s') where E' = E + {X --> x} and x = next(s) and s' = alloc(s) (S1 S2| Rest, E, s) -i-> (S1 | S2 | Rest, E, s) (S | Rest, E, s) -i-> (Rest, E, s') where S is not a declare or sequence statement and ([(S,E)],s) -->* (nil,s') ** Exceptions (2.7) Q: Why do we need exception handling? Why not just check return codes? error prone, non-local (non-modular) ------------------------------------------ EXCEPTION HANDLING EXAMPLE proc {Assert B Msg} if B then skip else raise 'Assertion failed: ' # Msg end end end try {Assert false oops} {Browse skipped} catch S#M then {Browse S#M} end {Browse hi} ------------------------------------------ Q: What happens in the above? ------------------------------------------ TRANSITIONS FOR EXCEPTIONS [try] ((try S1 catch X then S2 end, E) | Rest, s) --> ((S1, E) | (catch X then S2 end, E) | Rest, s) [raise] ((raise X end, E) | Rest, s) --> ((Sc, Ec') | Rest', s) where (catch Y then Sc end, Ec) | Rest' = findHandler(Rest) and Ec' = Ec + {Y -->E(X)} [raise-error] ((raise X end, E) | Rest, s) --> "Uncaught exception" where nil = findHandler(Rest) [catch] ((catch X then S2 end, E) | Rest, s) --> (Rest, s) ------------------------------------------ Q: Does the variable in a raise have to be determined? no! Q: How would you define findHandler? Q: What's that statement catch X then S2 end added in [try]? It's a semantics only statement, used in the semantics. Q: Why is its semantics to do nothing? Because it is only activated during a raise ------------------------------------------ SUGARS try S1 finally S2 end ==> try S1 catch X then S2 raise X end end S2 try S1 catch X then S2 finally S3 end ==> try try S1 catch X then S2 end finally S3 end ------------------------------------------ Q: How could we use pattern matching with try? Q: How would you desugar that? Q: What kind of data should be used for exceptions to help matching? records ** Functional Languages (2.8.1) *** foundational calculus ------------------------------------------ LAMBDA CALCULUS E ::= X | \X . E | E E | (E) parsing rules: scope of \X extends as far as possible application associates to the left example: \x . y z z means (\x . ((y z) z)) In Oz this is E ::= X | fun {$ X} E end | {E E} | (E) example: fun {$ X} {{Y Z} Z} end ------------------------------------------ This syntax is used in many papers... Q: In what way is this more primitive than the kernel langauge? Q: How would you write a TTS for the lambda calculus? *** functional programming on complete values The kernel allows partial values, and procedural syntax Q: How can we restrict the model to only work with complete values? - always bind variable to value when declared, i.e., only allow local X = V in S end local X={F Y1 ... Yn} in S end - use only function, not procedure syntax and translate nested calls before creation of data structure Then don't need unbound variables. Get a (strict) functional model, as in Scheme or SML. ** Entailment and disentailment (2.8.2.4) ------------------------------------------ ENTAILMENT X == Y means X and Y are structurally equal blocks if some nodes are different but one is unbound What happens when we do: declare R1 R2 X R1 = pig(weight:100) R2 = pig(weight:X) {Browse R1 == R2} declare R1 R2 X R1 = pig(weight:X) R2 = pig(weight:X) {Browse R1 == R2} declare R1 R2 X R1 = horse(weight:X) R2 = pig(weight:X) {Browse R1 == R2} ------------------------------------------ Q: What answers do these give? ** Static vs. Dynamic Typing (2.8.3) ------------------------------------------ STATIC VS. DYNAMIC TYPING def: A *type error* is def: A langauge has a *static type system* iff def: A *dynamic type system* catches type errors ------------------------------------------ ... an attempt to apply an operation to data outside its domain (as defined by the language) Q: Can a langauge have no type errors? Sure, BCPL does. Q: Is calling a number as a procedure a type error? Q: What are other examples? Q: What about accessing an array outside its bounds? not usually thought of as a type error Q: What about casting an object to a type it doesn't have in Java? Java doesn't think of it that way ... type errors are discovered before runtime. ... at runtime (in general). Q: Which is more general? Q: Which makes separate compilation easier to implement? Q: Which is better for exploratory programming? Q: Which is better for safety critical systems? Q: Which has faster compiled code? Q: Which does Oz have? There is a variant of Oz, called Alice, that is statically typed. Q: Is it possible to blend static and dynamic typing? Yes