Presentation is loading. Please wait.

Presentation is loading. Please wait.

 Flattening and Direct semantics  By example: Inheritance  Featherweight Jigsaw (FJig)  (nice and clean) surface syntax  Generalized inheritance.

Similar presentations


Presentation on theme: " Flattening and Direct semantics  By example: Inheritance  Featherweight Jigsaw (FJig)  (nice and clean) surface syntax  Generalized inheritance."— Presentation transcript:

1

2  Flattening and Direct semantics  By example: Inheritance  Featherweight Jigsaw (FJig)  (nice and clean) surface syntax  Generalized inheritance  I’ll gloss over its (ugly but equivalent) core syntax  Conclusions

3

4  Please think how you’d explain inheritance  to a muggle 1 ( 1 here, indicates someone who’s never heard of OO)  Odds are you’re thinking of flattening semantics

5 class C1 { void m1() {…} } class C2 extends C1 { void m2() {…} } It’s as we wrote C2 like this class C2 { void m1() {…} void m2() {…} } What does this mean?

6 Extended Language  Giving semantics of some feature by translating it away  Programs translated in (equivalent) programs that don’t use the feature Language class C2 extends C1 { void m2() {…} } class C2 { void m1() {…} void m2() {…} }  Extension flattened into the vanilla language  Let’s see pros and cons

7 class C1 { void m1() {…} } class C2 extends C1 { void m2() {…} } class C3 extends C2 { void m3() {…} } class C1 { void m1() {…} } class C2 { void m1() {…} void m2() {…} } class C3 { void m1() {…} void m2() {…} void m3() {…} }

8 class C1 { void m1() {…} } class C2 { void m1() {…} void m2() {…} } class C3 { void m1() {…} void m2() {…} void m3() {…} }  Lookup as easy as it can get  No changes in the definition (the program changes, not lookup)  For instance, lookup(C2, …)= (inheritance has been flattened out)

9 class C1 { void m1() {…} } class C2 extends C1 { void m2() {…} } class C3 extends C2 { void m3() {…} } class C1 { void m1() {…} } class C2 { void m1() {…} void m2() {…} } class C3 { void m1() {…} void m2() {…} void m3() {…} } the binary depends on

10  Intuitive: good tool for teaching/understanding  Been used to give the semantics of mixins, traits, … but  Poor implementation choice  Lot of compiling dependencies (unlike Java, like C++)  Code bloating

11

12  Please think how you’d implement inheritance  Odds are you’re thinking of direct semantics

13 Extended Language class C2 extends C1 { void m2() {…} }  Classes can be defined in new ways  Since programs are not translated, good old method lookup can’t work anymore Language class C1 { void m1() {…} } We can compute lookup(C, m)=… For instance, lookup(C1, m1)=… lookup(C2, m1)=???

14  Needs to know what extends means  For instance, lookup(C3, m2) starts from C3  Don’t find m2, so proceeds with C2  And finds m2 class C1 { void m1() {…} } class C2 extends C1 { void m2() {…} } class C3 extends C2 { void m3() {…} }

15 FlatteningDirect IntuitiveYESLess than the other Good old method lookup YESNO Is efficient?NOYES

16

17  class C ClassExpression  ClassExpression ::= BasicClass | merge ClassExpression1, ClassExpression2 | rename N to N’ in ClassExpression | hide N in ClassExpression | …others… BasicClass ::= { …constr/fields/methods… }

18  One constructor; takes any kind of parameters  Internal representation hidden from clients  A series of members: fields and methods  Members can be:  abstract  virtual  frozen  local no definition “someone” is expected to provide it there is a definition, but it can be later replaced there is a definition, that current clients will see forever (even if replaced) there is a definition, that no other object will ever see

19  Nice per se  More than that, can encode:  standard inheritance  mixins  traits  … it’s a general framework for sw composition  Wouldn’t be wonderful to have  an intuitive (flattening) semantics and  a (rather complex but) efficient (direct) one?  Actually, no it wouldn’t  … unless they’re equivalent! And they are!

20  class A { abstract void m(); frozen int answer() { return 41; } local int loc() { return 1; } }  class B { frozen int answer() { return 42; } virtual void m() { loc(); } local int loc() { return answer(); } }  class C merge (rename answer to wrongAnswer in A), B  …what’s new C().answer()? I’m “cheating” using  an extra-sugared syntax  primitive types and void

21  class C merge (rename answer to wrongAnswer in A), B  class C merge (rename answer to wrongAnswer in { abstract void m(); frozen int answer() { return 41; } local int loc() { return 1; } } ), B

22  class C merge { abstract void m(); frozen int wrongAnswer() { return 41; } local int loc() { return 1; } }, B

23  class C merge { abstract void m(); frozen int wrongAnswer() { return 41; } local int loc() { return 1; } }, { frozen int answer() { return 42; } virtual void m() { loc(); } local int loc() { return answer(); } }

24  class C merge { abstract void m(); frozen int wrongAnswer() { return 41; } local int loc() { return 1; } }, { frozen int answer() { return 42; } virtual void m() { loc’(); } local int loc’() { return answer(); } }

25  class C { // equivalent flattened definition frozen int wrongAnswer() { return 41; } local int loc() { return 1; } frozen int answer() { return 42; } virtual void m() { loc’(); } local int loc’() { return answer(); } }  now we can easily see what new C().answer() is  and, quite obviously, it’s 42

26 class A { abstract void m(); frozen int answer() { return 41; } local int loc() { return 1; } } class C merge (rename answer to wrongAnswer in A), B  again, what does new C().answer() means?  what is lookup(C, answer)? class B { frozen int answer() { return 42; } virtual void m() { loc(); } local int loc() { return answer(); } }

27 class A { abstract void m(); frozen int answer() { return 41; } local int loc() { return 1; } } class C merge (rename answer to wrongAnswer in A), B class B { frozen int answer() { return 42;} virtual void m() { loc(); } local int loc() { return answer(); } } lookup(C, answer) = lookup(merge …, answer) = = lookup((rename…), answer) and non-deterministically = lookup(B, answer)

28 lookup(rename FromN to ToN in ClassExpression, N)=  failure if N=FromN  lookup(ClassExpression, FromN) if N=ToN  lookup(ClassExpression, N) otherwise In the example: lookup((rename answer to wrongAnswer in A), answer) fails, so lookup(C, answer) = … 2 choices … = lookup(B, answer)

29 lookup(B, answer) = lookup( ClassExpression, answer) where ClassExpression is the class expression of B, which is a base (flatten) class. So, we can conclude. Believe it or not, I’ve just scratched the surface: direct semantics is no picnic

30  Flatten semantics: easy, intuitive  but “performs” poorly  Direct semantics can be (rather) complex  but it’s a good choice for implementation  FJig: general language for software composition  encompasses inheritance, mixin, traits….  Given both semantics and proved equivalent  Implemented interpreter as master-thesis:  Exploring the equivalence for feature requiring static types (e.g. overloading and static binding)  Investigating smart implementation techniques

31


Download ppt " Flattening and Direct semantics  By example: Inheritance  Featherweight Jigsaw (FJig)  (nice and clean) surface syntax  Generalized inheritance."

Similar presentations


Ads by Google