Joined September 2014
·

Yoav

Israel
·
·

BTW, I found a disturbing limitation in class composing(using traits) in regards to structural typing:

Say class A declares a dependency in abstract trait B and then gets instantiated with trait B1 (which of course extends B) - B1's ctor will not be called until A's ctor isn't finished.
Although this behaviour is understandable(the trait isn't extended, it is mixed in an already constructed class instance), it might lead to unexpected results when defining default members in B1's ctor (which is a good practice for reasons of immutability) - those would be null until A is constructed meaning that any call to a B1 method which uses these members will result in some kind of a NullPointer exception.

A workaround to this problem would be to use expressions rather than vals, e.g:
trait B1 extends B{
val name: String = "Richard" //causes NullPointer
def name: String = "Richard" //will work
}

@przemekpokrywka I guess what you meant was:
abstract trait A{definition}
trait B extends A{implementation}
trait B1 extends A{implementation}
trait B2 extends A{implementation}
class C{....}
val instance = new C with B/B1/B2...

In that case you're right but C cannot declare itself as extending A without implementing A's definitions - that wouldn't compile.

@przemekpokrywka, if I'm not mistaken, extending an abstract trait would compile only when implementing it's non defined methods (at least with scala 2.11).

@eranation, great article!

Achievements
1 Karma
0 Total ProTip Views
Interests & Skills