There are many interesting ideas in those messages. Very exciting. Only some comments: Doug writes: Maybe we can invent two new types of nodes in the class diagram, signatures and structures, and a new edge, a functor edge. Then signatures and structures are lists of classes & strategies (and types, when we add parametric polymorphism to Demeter), similar to how classes and interfaces are lists of data members and methods. So we have: signature: class graph plus strategies for that class graph. Those are exported from a module. The signature is the provided interface of the module. structure: implementation of a signature. Has a required interface described by a signature. Structures may be parameterized: they are called functors. The class graphs of the provided and required interface might overlap. We would like to draw only one class graph and use a strategy edge to define which part of the class graph provides the provided interface. What is a bit confusing is that we now have class graphs all over. Before, they only described the stored object structure. Now they describe higher-level structures. Boaz remarked that we should view a class graph edge as defining a strategy edge for implementing the class graph. This means that each part access is done through a strategy, leading to an extremely adaptive style. Doug writes: I suspect UML already has something along these lines, but I haven't looked at the spec in a while. Anyone have a recent copy? Did they ever get to 1.0? Yes, there is UML 1.0 and there is a book about UML: UML Distilled which I will use in COM 3360 this fall. UML is good for standardizing notation but probably not for giving insights into our module system. UML has support for derived edges and attributes (put a / in front of the part), interfaces (use a stereotype), packages and dependencies. Johan writes: What were the reasons behind the rules on page 531 ok Karl's book? They are for making the expansion of parameterized classes work for single inheritance systems like Java. The "bounded" restriction is for keeping our languages context-free. With parameterized classes you can define context-sensitive languages. Which of those rules should we give up for Demeter/Java? -- Karl ======================= From johan@ccs.neu.edu Mon Aug 4 11:45:59 1997 From: Johan Ovlinger To: lieber@ccs.neu.edu CC: dem@ccs.neu.edu Subject: Re: layered systems If I understand the idea, We want a module to map classgraphs on a higher layer to a lower layer, in such a way that other modules can be compiled w/o looking at the lower layer. As an example, we might have as a high level description (notice that B is optional): A = [B]. and the lower level be A : C | D. D = . C = E. E = B. (The high level desc must have B optional as A could be D, which has no B part. Class Graph analysers, start your engines.) Karl's proposition is that we can achive this mapping by producing prepackaged traversal snippets whilst compiling the module: to go from A to B on the high level, other modules simply call a.toB(); A::toB() is defined as ((C) this).get_E().get_B(); (looks a bit like a longgetter, no?) That is how I understood the gist of Karl's mail. Karl, could you clarify two points in your mail? 1) why interfaces? 2) what are the local_b things? Am I trying to understand them in the wrong context? Johan From ghulten@ccs.neu.edu Mon Aug 4 12:18:30 1997 Subject: Re: layered systems From: Geoff Hulten To: "Johan Ovlinger" , "Karl Lieberherr" cc: >As an example, we might have as a high level description (notice that >B is optional): > >A = [B]. > >and the lower level be > >A : C | D. >D = . >C = E. >E = B. > >(The high level desc must have B optional as A could be D, which has >no B part. Class Graph analysers, start your engines.) Yeah, but there is no reason that the lower level needs to contain an object of class B. The mapping between levels could (for example)construct a B object solely from the information contained in an E object. >Karl's proposition is that we can achive this mapping by producing >prepackaged traversal snippets whilst compiling the module: to go from >A to B on the high level, other modules simply call a.toB(); More likely a.get_b() or something like 'via A to B;' >A::toB() is defined as ((C) this).get_E().get_B(); (looks a bit like a >longgetter, no?) Exactly, in the case when the representation contains a B object. One thing that Johan implied here is that other 'modules' don't have access to the lower level representation. I agree that information hiding will be an important part of what ever solution we come up with. Karl kind of implied that Doug and I had implemented a layering system. All we have done is add a simplified form of derived edges to the demjava system. I think that figuring out what needs to be implemented is what I (and now professor wand and others) are working on. Maybe we'll have a slightly clearer picture after Professor Wand's presentation at seminar today. >That is how I understood the gist of Karl's mail. > >Karl, could you clarify two points in your mail? >1) why interfaces? >2) what are the local_b things? Am I trying to understand them in the >wrong context? I think the local_b things are a hack way of passing arguments to the code that calculates derived edges. -Geoff From johan@ccs.neu.edu Mon Aug 4 15:02:40 1997 Date: Mon, 4 Aug 1997 15:02:36 -0400 (EDT) From: Johan Ovlinger To: ghulten@ccs.neu.edu CC: lieber@ccs.neu.edu, dem@ccs.neu.edu Subject: Re: layered systems [Geoff responds] > Yeah, but there is no reason that the lower level needs to contain > an object of class B. The mapping between levels could (for > example)construct a B object solely from the information contained > in an E object. Now I'm kinda confused. In order to construct it, there has to be a description of it, no? I think I should make my thoughts a bit more concrete: In my view, a module consists of 4 Parts: 1) an Ideal (exported) class graph, and some exported operations defined on it 2) a number of imports. The unit of import is a module. We can refer to imported (ideal) classes by prepending the module name. To maintian flexibility, I think we should allow "import foo as bar", then to change imported module, only one location needs to be updated 3) a concrete class graph, which has both locally defined private classes and imported classes, and private operations on the classgraph. 4) a name map from the concrete class graph to the ideal. This is to hide the fact that some classes will be local and others imported. Until I read geoff's reply, I had forgotten about this. So in my hypothetical system, B would be defined locally. (this is probably what is meant by 'mapping between levels'). Now that I think about it in a concrete setting like this, I see that the interfaces might be very useful to perform the namemap for the imported classes. They are redundant for what I believe is the common case, and what I had in mind when asking the question originally: a locally defined class reexported as itself. I much obliged for the clarification. --------------------------------------------------------- Part 2: a cool thought. the main problem with imports is that the importer can only point to them. The importee has no notion of the importer, and as such can't have parts referring back to the importer. (unless we allow circular imports, which I strongly advise against) I just realised that parametrised classes are a great solution for this non-problem. I'm begining to really like the idea of the module system. Do we have to rethink the restrictions on pararametrised classes in the light of higher order classes? What were the reasons behind the rules on page 531 ok Karl's book? Esp #2 and #4? Johan From ghulten@ccs.neu.edu Mon Aug 4 21:00:43 1997 Subject: Re: layered systems Date: Mon, 4 Aug 97 21:01:38 -0400 To: "Johan Ovlinger" cc: >Now I'm kinda confused. In order to construct it, there has to be a >description of it, no? I think I should make my thoughts a bit more >concrete: > >In my view, a module consists of 4 Parts: > >1) an Ideal (exported) class graph, and some exported operations > defined on it Hrm, kind of like an SML signature. >2) a number of imports. The unit of import is a module. We can refer > to imported (ideal) classes by prepending the module name. To maintian > flexibility, I think we should allow "import foo as bar", then to > change imported module, only one location needs to be updated Hrm, kind of like the part of the functor where you bind signatures to functor formal parameters >3) a concrete class graph, which has both locally defined private > classes and imported classes, and private operations on the classgraph. Hrm, kind of like an SML structure. >4) a name map from the concrete class graph to the ideal. This is to > hide the fact that some classes will be local and others > imported. Until I read geoff's reply, I had forgotten about this. Hrm, kind of like the body of a functor that only contains statements of the from: Structure foo = formal.foo So we are leaving out: * allowing more than one structure to satisfy a single interface * allowing a structure to satisfy more than one interface * allowing more interesting functor bodies eg Structure foo = N(formal1.bar, formal2.baz) I have a little writeup that I based that babble err presentation that I gave at last weeks seminar on. The gist of it was that we would add an 'implementation edge' to the class graph notation. Any class with an outgoing 'implementation edge', say class C, would automagically become something like a signature. Any class, say S, with an incoming 'implementation edge' automagically becomes something like a structure. Then along next to the 'implementation edge' a programmer would provide code that says how class graphs rooted at S are turned into class graphs rooted at C at run time (a bit like a functor?) Hrm. -Geoff From dougo@ccs.neu.edu Mon Aug 4 21:15:03 1997 Date: Mon, 4 Aug 1997 21:14:47 -0400 From: Doug Orleans To: Geoff Hulten Cc: "Johan Ovlinger" , Subject: Re: layered systems Geoff Hulten writes: > I have a little writeup that I based that babble err presentation that > I gave at last weeks seminar on. The gist of it was that we would add > an 'implementation edge' to the class graph notation. Any class with an > outgoing 'implementation edge', say class C, would automagically become > something like a signature. Any class, say S, with an incoming > 'implementation edge' automagically becomes something like a structure. > Then along next to the 'implementation edge' a programmer would provide > code that says how class graphs rooted at S are turned into class graphs > rooted at C at run time (a bit like a functor?) This seems to limit structures (and signatures) to single classes (interfaces), or at best a tree rooted at a single class (interface). Maybe we can invent two new types of nodes in the class diagram, signatures and structures, and a new edge, a functor edge. Then signatures and structures are lists of classes & strategies (and types, when we add parametric polymorphism to Demeter), similar to how classes and interfaces are lists of data members and methods. I suspect UML already has something along these lines, but I haven't looked at the spec in a while. Anyone have a recent copy? Did they ever get to 1.0? --Doug