The successes and failures of a language as a language extension.
Download
Report
Transcript The successes and failures of a language as a language extension.
presented at ECOOP’03 workshop 15
The successes
and failures of
a language
as a
language extension.
Kasper B. Graversen
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
The role concept 1/2
Motivation for roles
Bridging
the gab between the problem
domain and the implementation domain
In the real world no object can be
understood outside its context(s)
In
Roles models a perspective of an object
the real world nothing is static
The role concept 2/2
Technical goals
Roles
are subtypes of their intrinsic
Applicable run-time and at the instance
level.
An object may play several roles
simultaneously—even roles of the same
time (comparable to Eiffel's repeated inheritance).
Statically type safe.
Has constituents, which augment existing
methods.
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
Approach
Host language: Java
We made a pre-compiler emitting
Java source code.
Our work mainly consisted of thinking
in code-transformations and loopholes
to get the desired end-result.
Implementation 1/3
Delegation (w. late binding of self.)
Every
call is made on an introduced
pointer (self), which is passed around with
each method call.
Roles became “part-object” which
delegated messages (for the methods
they inherited but did not overwrite).
Constituent methods forced us to redefine the delegation concept to
“latest possible binding of self”.
Implementation 2/3
class B {
void bar(){}
}
Role R for B { }
r =new R( new B() );
r.bar();
:B
:rolemanager
:R
:rolemanager
r
Implementation 3/3
(re-defining delegation)
class A {
:R
:A
void foo
a
c
foo
}
baz
Role R for A {
constituent c before foo {
baz();
:rolemanager
:rolemanager
}
void baz() {}
}
A a = new A(); Message receiver (= self) is a,
but a does not have a baz()
new R( a );
a.foo();
hence, during constituent
execution self must be the
constituent
(simplified version)
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
Main obstacles 1/6
No access to method dispatching
We
had to maintain and pass around a
self-pointer (in all methods and method calls)
Problematic when going “outside”, then
“inside” chameleon code in the same call,
as we then have two self references
Chameleon-Java
Java
Main obstacles 2/6
Typing
Impossible
to assign types to classes
(using interfaces is non-trivial and fields+
protected methods cannot be part of
the type).
Problematic to attach a role to a subtype of its intrinsic
A
foo()
R
pip()
B
foo() bar();
bar()
1.
2.
3.
4.
:B
:R
self = :R
R: delegates to intrinsic’s foo
B: calls self.bar()
self has no bar!
(but we know one exists!)
Main obstacles 3/6
Restricted access to properties – we
could only get access by using Java’s
inheritance.
Inheritted unwanted:
fields (memory inefficient)
methods,
since constituents could be
attached the intrisics’ methods, they had
to be executed if they were not
overwritten in the role.
We could not express dual
inheritance, due to lack of multiple
inheritance in Java.
Main obstacles 4/6
No field access detection
We
had to create accessor-methods and
transform the code to using these
Field access became virtual
Shadowing fields would result in faulty
programs
Java
programs could not use
Chameleon-compiled code unless using
accessor-methods which were not
present in the Chameleon source code.
Main obstacles 5/6
Hard to debug programs which the
Java compiler failed compiling
The
programmer had to know the steps
of, and the code transformations.
And then in his head, reverse the
transformations in order to find the
problem spot in the Chameleon code.
Main obstacles 6/6
Programming languages not only
delimits expressional power, they
delimit/direct our thoughts.
There
were concepts in the first article we
read on the subject (Kristensen and Østerbye 94), we
could not comprehend.
We invented things, the authors of the
above article had not thought of (but
which would be very important for their
implementations).
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
Advantages
It gave us a rocket start
In
2 days from start, we had rudimentary
roles (with faulty delegation it turned out later :-).
It was relatively easy to think in terms of
Java code-transformations rather than
assembler instructions.
Enabled us to use/play with small
programs to gain an understanding of
the concept.
Advantages
Extending the role concept was rather
straight forward
Symbiosis
between implementation and
conceptual extensions.
We believe we would not have come as
far with a lower-level implementation of
our role concept.
Existing Java programs could be used
in our Chameleon programs, and
vice-versa.
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
API is just as important
Ideas for new languages/extensions
must be tried in real world scenarios!
This is hard if the language is shielded
from the outside world
We
need
I/O (disc,database,network,keyboard,mouse)
Graphical User Interface
(elemental data structures)
Language extensions can usually
effortless use the host language API.
The presentation
The role concept
Our approach
What problems did we face
What did we find advantageous
about language extensions
API is just as important...
Conclusions
Conclusions
Extending Java was nice since
We
got a quick start
We had a huge API available
Existing programs could use Chameleon
classes.
We found it a manageable task to
extend the role concept in many
directions.
Conclusions
Extending Java was NOT nice since
Many
severe problems arise when really
grinding into the issues of the language.
Most things which seemed to be reusable
from the host language turns out to be
obstacles.
A userfriendly language extension
requires a parser, type checker, ‘code
mutator’ and a ‘host language emitter’
(almost?) as huge a task as building a
compiler from scratch.
The end...