Com S 641 meeting -*- Outline -*- * modules (2.13) Q: What's another kind of "." in C++? the :: One benefit of this discussion is to clear up some of the often-confused semantics of modules in C++ Q: How is a module like a record? both map names to values... meaning of both is an environment Q: What syntactic domain haven't we allowed to be named yet? declarations ------------------------------------------ MODULES (2.13) Modules are Abstract syntax: D ::= ... | Example: module LineM = { class Point = record x:newint, y:newint end; var p1:Point, var p2:Point; var arg:newint, var result:newint; proc set_p1_x = p1.x := @arg, proc set_p1_y = p1.y := @arg, proc set_p2_x = p2.x := @arg, proc set_p2_y = p2.y := @arg, proc x_length = result:= p1.x - p2.y }; class Line = record import LineM end; var x:Line, p1:LineM.Point in x.arg := 3; x.set_p1_x; p1.x := 4; LineM.arg := 2 ------------------------------------------ ... declaration abstractions ... module I = {D} | import I Q: Why is the invocation form a declaration? The typing rules and semantics are the eager ones ------------------------------------------ TYPING RULES FOR MODULES ___________________________________ pi |- module I={D}:{I:pi_1 dec} dec pi |- import I:pi_1 dec, if SEMANTICS FOR MODULES Should it be lazy or eager? [[pi|-module I={D}:{I:pi_1 dec} dec]]e s = [[pi |- import I:pi_1 dec]]e s = ------------------------------------------ ... pi |- D : pi_1 dec ... (I:pi_1 dec) \in pi Q: Should we give a module declaration lazy or eager evaluation semantics? think about the above program Q: For which declarations inside a module will it make a difference? only for variables (and modules!) for the rest they would be stopped by the lazy evaluation of other decls if we allow module indexing, will the vars be defined if we don't allocate them? But what about the variable in the record that imported LineM? it's shared (an alias) Lazy semantics (wrong): ... ({I=f}, s), where f(s') = [[pi |- D: pi_1 dec]]e s' ... f s, where (I=f) \in e Eager semantics: ... ({I=e1, s1), where (e1,s1) = [[pi |- D:pi_1 dec]]e s ... (e1,s), where (I=e1) \in e ------------------------------------------ DISCUSSION Eager evaluation allows sharing: module S = {var A:newint}; module M = {import S; proc INIT=A:=0}; module N = {import S; proc SUCC=A:=@A+1} in call M.INIT; call N.SUCC Let D be the declaration above. Let piS = {S={A:int loc}dec} piM = {M={A:int loc,INIT:comm}dec} piN = {N={A:int loc,SUCC:comm}dec} piSM = piS U piM pi = piSM U piN [[0 |- D:pi dec]]0 s = {by sample calculation...} ({S={A=l}, M={A=l,INIT=p}, N={A=l,SUCC=p'}}, s1) where (l,s1)= allocate(s) and p s' = [[piS U {A:int loc}|-A:=0:comm ]]({S={A=l},A=l}) s' and p' s' =[[piSM U{A:int loc}|-A:=@A+1 :comm ]]({S={A=l},M={A=l,INIT=p}, A=l}) s' ------------------------------------------ see sample-calculation.txt in this directory ------------------------------------------ Redeclaration: -- is the following okay? module S = {var A:newint}; module M = {import S; proc INIT=A:=0}; module N = {import S; proc SUCC=A:=@A+1}; import M; import N in call INIT; call SUCC ------------------------------------------ No, because A is redeclared by the second import but it's reasonable to want to allow this. Q: What should the language do? make it illegal? make A unaccessible? make it so you have to write S.A or M.A? Q: What's the difference between a module and a class? a class is lazily evaluated, a module is eagerly evaluated can the one simulate the other? use class K = D as coding for module M = {D} but sharing not simulated the other way around, declare records for the data, then a module to hold the class's procs