plan of the talk

Post on 24-Feb-2016

32 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Flattening versus Direct semantics for Featherweight Jigsaw Giovanni Lagorio , Marco Servetto and Elena Zucca. Plan of the talk. Flattening and Direct semantics By example: Inheritance Featherweight Jigsaw ( FJig ) (nice and clean) surface syntax Generalized inheritance - PowerPoint PPT Presentation

TRANSCRIPT

Flattening versus Direct semantics for Featherweight Jigsaw

Giovanni Lagorio, Marco Servetto and Elena Zucca

Plan of the talk 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

Flattening Semantics

The intuition of Inheritance Please think how you’d explain inheritance

to a muggle1

(1 here, indicates someone who’s never heard of OO)

Odds are you’re thinking of flattening semantics

Flattening Semantics of inheritanceclass 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?

ExtendedLanguage

The general idea 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

Pros: it’s intuitive 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() {…}}

Pros: good old method lookupclass 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)

class C1 { void m1() {…}}

class C2 extends C1 { void m2() {…}}

class C3 extends C2 { void m3() {…}}

Cons: compiling dependenciesclass C1 { void m1() {…}}class C2 { void m1() {…} void m2() {…}}class C3 { void m1() {…} void m2() {…} void m3() {…}}

the binarydepends on

Flattening Semantics, recap 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

Direct Semantics

The implementation of Inheritance Please think how you’d implement

inheritance

Odds are you’re thinking of direct semantics

ExtendedLanguage

class C2 extends C1 { void m2() {…}}

The idea 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 computelookup(C, m)=…

For instance, lookup(C1, m1)=…

lookup(C2, m1)=???

Extended method lookup

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() {…}}

A comparison

Flattening DirectIntuitive YES Less than the

otherGood old method lookup

YES NO

Is efficient? NO YES

Featherweight Jigsaw (FJig)

Flexible class definitions class C ClassExpression ClassExpression ::=

BasicClass | merge ClassExpression1,

ClassExpression2| rename N to N’ in ClassExpression | hide N in ClassExpression | …others…

BasicClass ::= { …constr/fields/methods… }

Basic class declaration 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

FJig 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!

An example 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

Flattening steps (1 of 5) 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

Flattening steps (2 of 5) class C merge

(rename answer to wrongAnswer in{ abstract void m(); frozen int answer() { return 41; } local int loc() { return 1; }}), B

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

Flattening steps (3 of 5) class C merge

{ abstract void m(); frozen int wrongAnswer() { return 41; } local int loc() { return 1; }} , B

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(); } }

Flattening steps (4 of 5) 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(); } }

Flattening steps (5 of 5) 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

Direct Semanticsclass 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(); } }

Direct Semanticsclass 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)

Lookup on a rename expression

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, solookup(C, answer) = … 2 choices … = lookup(B, answer)

Lookup on a namelookup(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

Conclusions and further work

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:

http://www.disi.unige.it/person/LagorioG/FJig/ Exploring the equivalence for feature requiring

static types (e.g. overloading and static binding) Investigating smart implementation techniques

Thank you

top related