This page is no longer maintained — Please continue to the home page at www.scala-lang.org

When to use self reference or composition?

3 replies
Antoras
Joined: 2010-05-23,
User offline. Last seen 1 year 19 weeks ago.

Hello,

have a look to the following code snippet:

trait T { def y = println("hello")}
class A {
self: T =>
def x = y
}
abstract class B {
val self: T
def x = self.y
}

val a = new A with T
val b = new B with T {
val self = this
}
a.x
b.x

Class A and B have a reference to trait T, A has a self reference and B
is using composition.

I see only two differences here: The first is in creating new objects
and the second in accessing T.

In B there is more syntactic sugar, I don't need to explicitly access
reference self and I don't need to bind the variable.

Are there another differences and are there some situations in which one
should preferred instead of the other?

Thanks
Antoras

Ken McDonald
Joined: 2011-02-13,
User offline. Last seen 42 years 45 weeks ago.
Re: When to use self reference or composition?
Well, I'd say there are big differences.
The most significant is that in B, you do not have a _guarantee_ that your object of type T is in fact the same object as your object of type A; that depends entirely on the assignment your making, which is a potential point of error.
As well, not being able to say "b.y" can get pretty annoying once your classes start becoming large and complex.
Finally, the "direction" in which you're using self-typing is opposite to the direction I typically use it (not that I'm the last word on the matter). As an example, I currently have some code that defines a Node class, which is a structural type--it is part of a tree. I also have a trait called a Box, which draws things onscreen, and can be inherited by certain types of Nodes that have a graphical representation. However, a Box, in order to do its work, needs access to data in the node. So, to give a simplified representation:
class Node {...}
trait Box {    this: Node => ...}
class ViewableNode extends Node with Box {...}
In other words, self typing is (here) used to indicated that a trait will only ever be inherited from by a particular type--which enables the trait to use the methods and data of that, type, which would not otherwise be possible.
Hope this helps,Ken
Antoras
Joined: 2010-05-23,
User offline. Last seen 1 year 19 weeks ago.
Re: Re: When to use self reference or composition?

Thanks for your response. Your example can also be used with composition:

class Node {...}

trait Box {
val self: Node; ...}

class ViewableNode extends Node with Box {val self = this; ...}

There is no difference with exception of the syntactic clues.

Btw., some days ago I asked this question on StackOverflow[1].

[1]
http://stackoverflow.com/questions/7177334/when-to-use-self-references-o...

On 27.08.2011 20:59, Ken McDonald wrote:
> Well, I'd say there are big differences.
>
> The most significant is that in B, you do not have a _guarantee_ that
> your object of type T is in fact the same object as your object of
> type A; that depends entirely on the assignment your making, which is
> a potential point of error.
>
> As well, not being able to say "b.y" can get pretty annoying once your
> classes start becoming large and complex.
>
> Finally, the "direction" in which you're using self-typing is opposite
> to the direction I typically use it (not that I'm the last word on the
> matter). As an example, I currently have some code that defines a Node
> class, which is a structural type--it is part of a tree. I also have a
> trait called a Box, which draws things onscreen, and can be inherited
> by certain types of Nodes that have a graphical representation.
> However, a Box, in order to do its work, needs access to data in the
> node. So, to give a simplified representation:
>
> class Node {...}
>
> trait Box {
> this: Node => ...}
>
> class ViewableNode extends Node with Box {...}
>
> In other words, self typing is (here) used to indicated that a trait
> will only ever be inherited from by a particular type--which enables
> the trait to use the methods and data of that, type, which would not
> otherwise be possible.
>
> Hope this helps,
> Ken

Ken McDonald
Joined: 2011-02-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: When to use self reference or composition?
You can do it that way of course, but why would you choose a more confusing, more verbose, and more confusing (especially in the Box code that accesses Node) way of doing things? Plus the fact that you _still_ have no absolute guarantee that Box.self is the same Node Box is inherited by?
Like many programming features, self-typing is not only aimed at allowing you to do things that would otherwise be impossible (I suspect someone more talented than I could come up with such examples), but also to make coding simpler, more obvious, and more robust.
Cheers,Ken

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland