mixins etc.

View: New views
1 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Re: mixins etc.

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Alex Tkachman schrieb:
[...]
> interface MyTrait {
>    def getValue ()
>
>   public static class Trait {
>    public static def getValue (MyTrait self) {
>       self.@myValue
>    }
>   }
> }
 >
> class X extends Y implements Z, MyTrait {
>    int myValue
>
>    def getValue () {
>       MyTrait.Trait.getValue(this)
>    }
> }

hmm... I see a potential problem here... not sure how you want to
realize this in bytcode in the end, but .@ suggests that you want to
change the field using Groovy. Using Java it is not possible without
reflection tricks, since the field is private, using Groovy this may
fail too, because if the field is private and you have a class extending
X, then this new class won't have the private field or a different one
even. meaning .@ will either mean the wrong field, or it will simply fail.

> - Trait is compile time, effecting hierarchy and preserving type
> information construction. So you can use instanceof
>
> assertTrue new X () instanceof MyTrait
>
> - Trait has no its own state but require derived class to provide
> necessary fields/properties
> - Trait applied to class enforce addition of all methods not yet
> presented in the class and super classes
> - Trait applied to class enforce addition of all properties not yet
> presented in the class and super classes

enforce addition of all methods/properties of the trait I guess

> - Trait syntax allows to use them for creating mixin definition
> (static methods with 1st param)

sorry, I don't understand what you mean here

> Q1) what happens to a private method in the toolbox?
>
> My idea is that only methods without modifiers becomes methods of
> interface.  Any implemented methods becomes members of trait
> implementation and any static implemented methods becomes static
> methods of Trait
>
> trait MyTrait {
>    def getValue () {
>       getDoubleValue ()
>    }
>
>    private def getDoubleValue () {
>      2 * value
>    }
>
>    static getStaticValue () {
>      0
>    }
> }
>
> means
>
> interface MyTrait {
>    def getValue ()
>
>   public static class Trait {
>    public static def getValue (MyTrait self) {
>       self.getDoubleValue ()
>    }
>
>    private static def getDoubleValue (MyTrait self) {
>      2 * self.value
>    }
>
>    static getStaticValue () {
>      0
>    }
>   }
> }

ehm... self is of type MyTrait, the method getDoubleValue is define in
Trait. There is no connection between them. Meaning: you try to call the
method on the class the trait has been applied to and getDoubleValue()
will be called as a method of this class, getDoubleValue will not be
called on MyTrait$Trait. In the end it will probably result in lost
method for Trait and in a MissingMethodException if getValue is called.

You are sure about this implementation?

> (Q2) how to call the original method?
>
> Do you mean how you call  trait method from Object implementing trait?

I mean this:

class X {
   def foo(){1}
}

trait T {
   def foo(){2}
}

class Y extends X with T {}

def y = new Y()
assert y.foo() == ???

I guess it will be 2 here, but then.. is there a way to call X.foo from
the trait?

> Because in my concept own methods of class has priority under methods
> of trait. BTW, it is a big difference with runtime mixins because in
> case of mixin you want to replace method of original class.

I see.. so the assert would assert to 1, not 2, right? Of course the
question is then how to call the Trait method... on the other hand if
such a trait can not have a state and the methods are all static anyway,
then I see no need for a special syntax like:

> My idea is to use TraitClass.this.method notation to call Trait
> method. But I am open to other good suggestions
>
> class X extends Y implements Z with MyTrait {
>    int myValue
>
>    def getValue () {
>       MyTrait.this.getValue ()
>    }
> }

like this one... just do MyTrait.Trait.getValue(). MyTrait.this.getValue
is to near to inner classes... remember they are on their way to groovy too!

> (Q3) can I maintain a static state in the toolbox?
>
> Yes you can
>
> static non-final fields of trait becomes static fields of inner class
> and involved in to creation of property index

ok

> (Q4) can I maintain a non static state in the toolbox?
>
> Short answer is no.

hmm... that limits their usability as modules you simply attach.

> The long answer is yes, we can try. If non-abstract class doesn't
> implement some getters/setters required by parent trait we can
> automatically create necessary properties.
>
> I am also pretty much like a idea of transforming uninitialized
> properties in to getter/setter definition.
>
> trait MyTrait {
>    def value
> }
>
> class X with MyTrait {
> }
 >

> means
>
> interface MyTrait {
>    def getValue ()
>    void setValue (newValue)
> }
>
> class X implements MyTrait {
>   def value
> }

why only uninitialized? why not follow classes here? Also, what is the
rule here for a static state version a non static state?

> (Q5) How will a closure resolve its methods/properties when in the toolbox?
>
> I think it should do it exactly on natural way - 'self' becomes owner
> and delegate when closure created as 'this' does in normal code.

ok, then what is the meaning of "this" in a closure in a trait...
because if we would simply generate the closure as it is now, then
thisObject and owner would be MyTrait$Trait, since we are in a static
method. If you want to change this and make self the value for owner and
thisObject, then we need to change the closure generation at this point
pretty much... sadly this part is a fragile piece of code..

> (Q6) is the toolbox getProperty/setProperty/invokeMethod/missingMethod
> method overwriting the one in the class th toolbox is applied to?
>
> I think yes in case if class or super classes doesn't provide their
> own (non-syntetic) implementation

hmm... so if the super class defines them, the trait won't do.... I then
have to make the call manually... becomes a bit useless then.

> (Q7) can a toolbox provide a constructor?
>
> Yes.
> But you should call it manually from constructor

can you give an example please

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


< Prev | 1 - 2 - 3 | Next >