CS 541 Lecture -*- Outline -*- * BeCecil, a Cecil-like multimethod language ** semantics *** models of objects ------------------------------------------ SEMANTIC MODELS OF OBJECTS objects as records (e.g. Smalltalk): !--------------------------! ! a Point object ! !--------------------------! | x ! *-----------> | y ! *-----------> !--------------------------! ! equal ! method(p2) ! ! print ! method() ! ! ... ! ... ! !--------------------------! objects with just data (CLOS, Dylan): !--------------------------! ! a Point object ! !--------------------------! | x ! *-----------> | y ! *-----------> !--------------------------! !-----------------------------------! ! equal generic function ! !-----------------------------------! ! Point x Point ! method(p1,p2) ! ! ClrPnt x ClrPnt ! method(cp1,cp2) ! !-----------------------------------! ------------------------------------------ (after pictures by Castagna et al.) really, we should distinguish Point from Point_pro, but it's too much of a pain for getting this idea across... ------------------------------------------ SEMANTIC MODELS OF OBJECTS (2) objects are just identities (BeCecil) !--------------------------! ! a Point object ! !--------------------------! !-----------------------------------! ! x generic function ! !-----------------------------------! ! Point ! storage(p) ! !-----------------------------------! !-----------------------------------! ! y generic function ! !-----------------------------------! ! Point ! storage(p) ! !-----------------------------------! !-----------------------------------! ! equal generic function ! !-----------------------------------! ! Point x Point ! method(p1,p2) ! ! ClrPnt x ClrPnt ! method(cp1,cp2) ! !-----------------------------------! ------------------------------------------ so it's all turned "inside out". (This follows some of the work of Abadi and Cardelli) *** storage tables ------------------------------------------ STORAGE TABLES example storage table for "x" !------------------------------! ! ! ! |----------------!-------------! | ! ! |----------------!-------------! ! ... ! ... ! |----------------!-------------! | (default) ! 0 ! !------------------------------! ------------------------------------------ fill in the empty parts of the picture Q: Can we generalize this idea to multiple "arguments"? then get a "n to 1" relation Q: so how would you handle arrays? ------------------------------------------ VARIABLES AS STORAGE TABLES object i i inherits GenericFun_pro i has storage() := 3 produces |--------------------| | () | | |--------------------| | (default) | 3 | |--------------------| Use: ------------------------------------------ Q: how would you desugar this? ... i() ... i() := 5 *** multiple dispatch to generic functions ------------------------------------------ GENERIC FUNCTION CALL EXAMPLE def: a *generic function* is example: myPt() := mkPoint(3,4) myCP() := mkClrPnt(3,4,red) equal(myPt(), myPt()) equal(myPt(), myCP()) equal(myCP(), myPt()) equal(myCP(), myCP()) ------------------------------------------ ... a collection of methods and storage tables (for now) Q: What case gets run in each case? any errors? Draw a picture of the tuple inheritance relationships Point x Point -- method 1 / \ ClrPnt x Point Point x ClrPnt \ / ClrPnt x ClrPnt -- method 2 and describe how this affects what method is called (also tie in with overriding definition on next slide) Q: Does this solve (some of) the binary methods problem? ------------------------------------------ SEMANTICS OF GENERIC FUNCTION CALL (simplified multiple dispatch) def: a *case* is def: let the *specializers of a case* are def: a case c1 *overrides* c2 iff Meaning of call: f(e1, ..., en) 1. Evaluate e1,...,en to values v1,...vn 2. Let applicable(f,(v1,...,vn)) be the set of all cases in f such that 3. There must just 1 case in applicable(f,(v1,...,vn)) 4. Bind the actuals to the formals and invoke that case ------------------------------------------ Q: what would the meaning of an assignment be? Q: could we generalize the notion of a method to allow assignment? ------------------------------------------ SINGLE VS. MULTIPLE DISPATCH In *single dispatch* langauges the method found is based on In *multiple dispatch* languages the method found is based on ------------------------------------------ ... the class of the receiver (1st arg) ... the class of all the arguments Q: What languages are examples of each? ** the language BeCecil *** Point example **** desugared code ------------------------------------------ POINT EXAMPLE (desugared and untyped version) object Point_pro Point_pro inherits any object x x inherits GenericFun_pro x has storage(p@Point_pro) := 0 object y y inherits GenericFun_pro y has storage(p@Point_pro) := 0 object equal equal inherits GenericFun_pro equal has method(p1@Point_pro, p2@Point_pro) { and(equal(x(p1),x(p2)), equal(y(p1),y(p2))) } ------------------------------------------ explain these **** sugars ------------------------------------------ SYNTACTIC SUGARS SM "Make your language sweeter" Idea: find recurring patterns of syntax, ------------------------------------------ ... automate their generation by humans Q: What examples do we have in the Point example? object o o inherits c <== object o inherits c object g g inherits GenericFun_pro <== gf g gf g g has storage(x@y_pro) := E <== field x of y_pro := E **** sugared version ------------------------------------------ POINT EXAMPLE (sugared version) object Point_pro inherits any field x of Point_pro := 0 field y of Point_pro := 0 gf equal equal has method(p1@Point_pro, p2@Point_pro) { and(equal(x(p1),x(p2)), equal(y(p1),y(p2))) } ------------------------------------------ explain the intuition behind all of this notation. Q: Who benefits from this sugaring? *** object creation ------------------------------------------ OBJECT CREATION -- static object myPoint inherits Point_pro ------------------------------------------ ... gf mkPoint mkPoint has method(i@int_pro, j@int_pro) { object res inherits Point_pro -- dynamic x(res) := i; y(res) := j; res } the block structure allows objects to be created dynamically, but in essence, objects are only created with the object declaration *** color point example ------------------------------------------ COLOR POINT object ClrPnt_pro inherits Point_pro field c of ClrPntPro := clear ------------------------------------------ ... equal has method(cp1@ClrPnt_pro, cp2@ClrPnt_pro) { and(equal(c(cp1), c(cp2)), equal(cp1@Point, cp2@Point)) } *** objects/types, inheritance/subtyping objects and types, and inheritance and subtyping are orthogonal (point out this is unusual) each has separate declarations. say how to type-check a method, because can access instance variables of a formal that is specialized parameters must be passed by constant (can't assign to formal) *** information hiding Q: have we lost anything in going to this kind of language? so far any part of the program can access the data suppose we want to have grayscale points, with a pro an integer between 0 and 255 ------------------------------------------ HIDE DECLARATION object Grayscape_pro inherits any hide -- private delarations in -- public declarations initialize has method(c@Grayscale_pro, inten@float_pro) { := truncate(multiply( min(max(0.0, inten) 1.0), 255.0)); c } intensity has method(c@Grayscape_pro){ divide(mkFloat( , 255.0)) } paint has method(c@Grayscale_pro, r@region_pro) {...} end intensity has acceptor(c@Grayscale_pro) := f { initialize(c, f) } ------------------------------------------ ... object scale scale inherits GenericFun_pro scale has storage(c@Grayscale_pro) := 0 ... scale(c) ... scale(c) Q: does this maintain the invariant in spite of clients?