I think you're mixing two different (but similar) concepts together.
The basic traits feature of scala allows you to define default
implementations in interfaces, which any implementing classes
automatically pick up on unless you override them. It's very similar
to multiple inheritance, except that there's no sharing of state: A
trait's fields aren't inherited by any classes that implement the
trait. Just the methods.

Your proposed syntax isn't java-legal. You can't just dump an
annotation inside a class scope, it has to be attached to something.
Lombok can sort of hack grammar (see the disableCheckedExceptions
hack), but if we're going to hack grammar, you have the freedom to
come up with a better syntax than that.

Syntax-wise, trying to be vanilla-java-grammar compatible is going to
look ugly and hacky, so lets just bite the bullet on that one and
accept that it'll need a grammar hack. Then you could make this as
simple as:

MyObject myObject = new MyObject() with MutableTreeNode: new
MutableTreeNodeTrait();

Note how we're passing in an object and not a class (unless you
intended this to actually copy over the implementation, which is going
to make upgrading things a massive pain in the behind, passing in an
instance is easier all around. Less reflection = win). You can also
chain this, with commas:

MyObject myObject = new MyObject() with java.util.List: new ArrayList
(), Runnable: new Runnable() {
    public void run() { /* run code */ }
};


A third aspect of traits is that you can have an interface (well, a
trait, in scala speak) implement some but not all methods; whatever
isn't implemented MUST be implemented by subclasses (i.e.: abstract).
You can't do this with the @Delegate proposal as easily. But then
again, in scala you can't use a trait unless it's specifically marked
as a trait, and @Delegate suffers from no such drawbacks. Fixing this
to be similar to scala is going to be a lot more hacky: lombok would
have to generate calls into an abstract class, so in practice it would
have to create a subclass of the abstract class, add dummy
implementations for all abstract methods (they'll never be called),
and generate wrapper calls into this dummy subclass for all methods
that did have implementations. Fortunately, if we're going to mess
with the grammar, we're in the clear, mostly:

public interface Similarity {
    public boolean isSimilar(Object other);
    public boolean isNotSimilar(Object other) {
        //Hey, lookit, a method body in an interface. Lombok can make
it legal.
        return !isSimilar(other);
    }
}

which lombok would translate to an interface together with an abstract
class that implements the interface, as an inner class of the
interface (that's java legal today). You can then write something
like:

public class Foo with Similarity {
    public boolean isSimilar(Object other) { return false; }
}

The 'with' there indicates you want the mixin functionality (we'll
leave implements alone, don't want to add too many surprises, and
we've already decided 'with' is going to be a keyword). Lombok will
then have to do rather a lot of magic to make this tick; it'll
subclass the abstract class inside Similarity as a non-static inner
class of Foo, adding wrapper calls back to the Foo instance for all
abstract methods (e.g. isSimilar). It'll then add wrapper calls into
this inner class for all methods in the Similarity interface that have
implementations (e.g. isNotSimilar), and which have not been
implemented directly by Foo. A pretty big wart in all this is that
changing Similarity later without also recompiling Foo is not going to
update Foo (whereas if you did this with subclasses, it would update),
but I don't think there's a way around that, the JVM just isn't that
flexible. I doubt scala do that either, in fact.

Bottom line: Scala's "with" keyword is pretty neat. Lombok certainly
doesn't aim to turn java into scala, but taking only the truly
excellent bits of scala should be good.

Hacking grammar rules is much more complicated than @Delegate though -
@Delegate is a couple orders of magnitude easier to add to Lombok, so
we'll start with that, and see where it goes.

On Aug 27, 9:50 pm, Graham Allan <[email protected]> wrote:
> > If someone has a better idea I'd love to hear it.
>
> I don't proclaim that, but I have a suggestion.
>
> This seems to be such a similar idea to traits* that it may be worth making
> the leap to them if you consider them to be more powerful. One thing with the
> delegates idea is that they don't allow 'bolting on' the behaviour if you
> don't have access to the source file (correct me if I'm wrong).
>
> An example of this could be the mixin demonstrated by the java-mixins creator:
>
> MyObject myObject = new MyObject() {
>         @With(interface = MutableTreeNode.class,
>                         implementation = MutableTreeNodeTrait.class)
>
> }
>
> Would make MyObject implement MutableTreeNode and have an implementations
> methods bolted in. Of course, there's drawbacks to this that aren't there
> with @Delegate: the new class created by the above example has the
> performance disadvantages of being compiled to a new class. @Delegates can
> also have state, which could be beneficial.
>
> May be off-target with some of these comments: I'm sure you'll let me know ;-)
>
> But the @Delegate description sounds really good.**
>
> * maybe not in Scala, I'm not familiar with exactly how they work.
> ** I have thought how it would be useful 
> before:http://stackoverflow.com/questions/254276/would-syntax-for-compositio...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to