trait X extends Y vs trait X {this: Y=> }

View: New views
7 Messages — Rating Filter:   Alert me  

trait X extends Y vs trait X {this: Y=> }

by Ken Scambler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi everyone,
I am a little confused by the two ways to indicate that a trait must form part of a given concrete class: extension versus self-types, as shown in the subject.  I have noticed that there are some differences in behaviour between the two.

Can anyone help explain the difference between them, and what situations benefit from using one or the other?

Thanks for you time,
Ken

Re: trait X extends Y vs trait X {this: Y=> }

by Josh Suereth :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The self type only enforces that you are *mixed-into* a particular type.  A trait that extends another could possibly be used standalone.

I would reserve self-types for things that truly are just mixins, and a "class instantiation concern".  This means the following:

trait X extends Y // X *is a* Y

trait X { self : Y => ... }    // X is a helper that can be used with a Y.   I would tend to prefer this over aspects for specific kinds of mixin functionality.

An example from EJB (yes... I know)

trait BaseDataAccessEJB {
   def tx : UserTransaction
   def entityManager : EntityManager
}


trait TransactionHelper { self : BaseDataAccessEJB =>

   //This is a toy implementation, in reality there are far more concerns to worry about in this method
   def transactional(f : => A) : A = {
          tx.start()
         try {
              f
          } finally {
              tx.commit()
          }
   }
}


Then when creating a new EJB I can do   class MyEJB extends BaseDataAccessEJB with TransactionHelper



I hope that helps,

- Josh

On Fri, Nov 6, 2009 at 7:35 PM, Ken Scambler <ken.scambler@...> wrote:

Hi everyone,
I am a little confused by the two ways to indicate that a trait must form
part of a given concrete class: extension versus self-types, as shown in the
subject.  I have noticed that there are some differences in behaviour
between the two.

Can anyone help explain the difference between them, and what situations
benefit from using one or the other?

Thanks for you time,
Ken
--
View this message in context: http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html
Sent from the Scala - User mailing list archive at Nabble.com.



Re: trait X extends Y vs trait X {this: Y=> }

by David Hall-17 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, Nov 6, 2009 at 4:47 PM, Josh Suereth <joshua.suereth@...> wrote:
> The self type only enforces that you are *mixed-into* a particular type.  A
> trait that extends another could possibly be used standalone.
>
> I would reserve self-types for things that truly are just mixins, and a
> "class instantiation concern".  This means the following:

It can also be used to influence the linearization order of the
traits. Maybe one should be careful in using this feature, but notice
the difference in:

scala> trait Foo { def foo = println("Foo") }
defined trait Foo

scala> trait Bar extends Foo { override def foo { println("Bar"); super.foo } }
defined trait Bar

scala> trait Baz extends Foo { this : Bar => override def foo {
println("Baz"); super.foo; } }
defined trait Baz

scala> val a = new Bar with Baz;
a: java.lang.Object with Bar with Baz = $anon$1@ee13d0

scala> a.foo
Baz
Bar
Foo

scala> val b = new Baz with Bar;
b: java.lang.Object with Baz with Bar = $anon$1@4deff4f

scala> b.foo
Bar
Baz
Foo

<<<<<Versus>>>>

scala> trait Foo2  { def foo = println("foo"); }
defined trait Foo2

scala> trait Bar2 extends Foo2 { override def foo { println("bar");
super.foo } }
defined trait Bar2

scala> trait Baz2 extends Bar2 { override def foo { println("baz");
super.foo } }
defined trait Baz2

scala> new Bar2 with Baz2 foo
baz
bar
foo

scala> new Baz2 with Bar2 foo
baz
bar
foo

-- David

>
> trait X extends Y // X *is a* Y
>
> trait X { self : Y => ... }    // X is a helper that can be used with a Y.
> I would tend to prefer this over aspects for specific kinds of mixin
> functionality.
>
> An example from EJB (yes... I know)
>
> trait BaseDataAccessEJB {
>    def tx : UserTransaction
>    def entityManager : EntityManager
> }
>
>
> trait TransactionHelper { self : BaseDataAccessEJB =>
>
>    //This is a toy implementation, in reality there are far more concerns to
> worry about in this method
>    def transactional(f : => A) : A = {
>           tx.start()
>          try {
>               f
>           } finally {
>               tx.commit()
>           }
>    }
> }
>
>
> Then when creating a new EJB I can do   class MyEJB extends
> BaseDataAccessEJB with TransactionHelper
>
>
>
> I hope that helps,
>
> - Josh
>
> On Fri, Nov 6, 2009 at 7:35 PM, Ken Scambler <ken.scambler@...> wrote:
>>
>> Hi everyone,
>> I am a little confused by the two ways to indicate that a trait must form
>> part of a given concrete class: extension versus self-types, as shown in
>> the
>> subject.  I have noticed that there are some differences in behaviour
>> between the two.
>>
>> Can anyone help explain the difference between them, and what situations
>> benefit from using one or the other?
>>
>> Thanks for you time,
>> Ken
>> --
>> View this message in context:
>> http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html
>> Sent from the Scala - User mailing list archive at Nabble.com.
>>
>
>

Re: trait X extends Y vs trait X {this: Y=> }

by Daniel Sobral :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, let me put it another way. If you say X extends Y, then you are saying X has Y's implementation. If you say self: Y =>, you are saying the class you are mixed into must implement interface Y.

In the first case, the class mixing X in can't choose a descendant of Y, in the second it can.

On Fri, Nov 6, 2009 at 10:35 PM, Ken Scambler <ken.scambler@...> wrote:

Hi everyone,
I am a little confused by the two ways to indicate that a trait must form
part of a given concrete class: extension versus self-types, as shown in the
subject.  I have noticed that there are some differences in behaviour
between the two.

Can anyone help explain the difference between them, and what situations
benefit from using one or the other?

Thanks for you time,
Ken
--
View this message in context: http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html
Sent from the Scala - User mailing list archive at Nabble.com.




--
Daniel C. Sobral

Veni, vidi, veterni.

Re: trait X extends Y vs trait X {this: Y=> }

by Miles Sabin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Nov 7, 2009 at 7:33 PM, Daniel Sobral <dcsobral@...> wrote:
> Well, let me put it another way. If you say X extends Y, then you are saying
> X has Y's implementation. If you say self: Y =>, you are saying the class
> you are mixed into must implement interface Y.
> In the first case, the class mixing X in can't choose a descendant of Y, in
> the second it can.

It can in both cases,

scala> class A
defined class A

scala> class B extends A
defined class B

scala> trait C extends A
defined trait C

scala> class D extends B with C
defined class D

Cheers,


Miles

--
Miles Sabin
tel: +44 (0)7813 944 528
skype:  milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

Re: trait X extends Y vs trait X {this: Y=> }

by Dimitris Andreou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hmm. Now I realize that both " this: A =>" and "self: A =>" are there.
Strange redundancy (assuming they are equivalent). Anyone knows why
this is so?

2009/11/7 Daniel Sobral <dcsobral@...>:

> Well, let me put it another way. If you say X extends Y, then you are saying
> X has Y's implementation. If you say self: Y =>, you are saying the class
> you are mixed into must implement interface Y.
> In the first case, the class mixing X in can't choose a descendant of Y, in
> the second it can.
>
> On Fri, Nov 6, 2009 at 10:35 PM, Ken Scambler <ken.scambler@...>
> wrote:
>>
>> Hi everyone,
>> I am a little confused by the two ways to indicate that a trait must form
>> part of a given concrete class: extension versus self-types, as shown in
>> the
>> subject.  I have noticed that there are some differences in behaviour
>> between the two.
>>
>> Can anyone help explain the difference between them, and what situations
>> benefit from using one or the other?
>>
>> Thanks for you time,
>> Ken
>> --
>> View this message in context:
>> http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html
>> Sent from the Scala - User mailing list archive at Nabble.com.
>>
>
>
>
> --
> Daniel C. Sobral
>
> Veni, vidi, veterni.
>

Re: trait X extends Y vs trait X {this: Y=> }

by Francois Armand-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dimitris Andreou a écrit :
> Hmm. Now I realize that both " this: A =>" and "self: A =>" are there.
> Strange redundancy (assuming they are equivalent). Anyone knows why
> this is so?

It's just a binding name. You can use whatever is meaningful for your
use case, and "self" or "this" are conventional name.

But you can rebind "this" to something else without the type annotation,
for example to make reference to that "this" in inner classes.

Ex:
class Outer(name:String) {
     outer =>
     class Inner {
         def whoOwnsMe() {
             println( outer.name )
         }
     }
}


--
Francois Armand
http://fanf42.blogspot.com