Why trait "extends" class instead of "with" when class extends only a trait(s)?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Why trait "extends" class instead of "with" when class extends only a trait(s)?

oss.mlists
Hi,
I'm used to understand inheritance like "what it is" (or behave as) and mixins as "what is has". Anytime I see things like "class Person extends Logging" it confuses me. Why we can't write "class Person with Logging"? Is there any reason for it, like Java interop, or it has been overseen?

The only solution I'm aware of to adhere to formalism would be to write "class Person extends AnyRef with Logging":( (I haven't actually try it though)

Many thanks.
Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

Kevin Wright-3
It makes more sense if you consider the class to extend a single union of the classes/traits being inherited.

As in:

class Person extends Logging
class Person extends (AnyRef with Logging)
class Person extends (Bibble with Bobble with Logging)

Where Bibble with Bobble with Logging” is a perfectly valid type in Scala


On 29 January 2016 at 10:11, Petr Novak <[hidden email]> wrote:
Hi,
I'm used to understand inheritance like "what it is" (or behave as) and mixins as "what is has". Anytime I see things like "class Person extends Logging" it confuses me. Why we can't write "class Person with Logging"? Is there any reason for it, like Java interop, or it has been overseen?

The only solution I'm aware of to adhere to formalism would be to write "class Person extends AnyRef with Logging":( (I haven't actually try it though)

Many thanks.
Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
Kevin Wright
mail: [hidden email]
gtalk / msn : [hidden email]
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

oss.mlists
Unfortunatelly it doesn't help me or I just don\t get it. I still have to lookup on code review how Logging is implemented if it is trait or an engineer was ignorant:)

I think I have realized one possible advantage. When I change class to trait I don't have to go to every usage source code and change "with" to "extends". IDE refactoring should cover it though (I haven't tried in IDEA). Changing trait to class has high chance to break.

Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

Roland Kuhn
It might help to realize that “with” has nothing to do with traits, and that “extends” is not so much about inheritance but about types.

rule 1: every class “extends” a type—it none is given then AnyRef is assumed
rule 2: types can be combined using “with”, creating an intersection of them (i.e. the resulting type contains all values that have the properties from all of the combined types)

Therefore it does not make sense to write class A with Logging: this would try to define “A with Logging” in terms of AnyRef, but what we really want is to define “A” in terms of “AnyRef with Logging”.

Given the following:

class Person extends Logging {
  def name: String
}

We declare a new class named Person that extends the type Logging (incidentally this means inheriting all the properties or members of this type) with a refinement that adds another property called “name” of type “String”. The most interesting part is not that Logging’s properties are inherited, but that Person is a subtype of Logging. This is a change compared to Java which focuses on which methods get pulled together on which classes (i.e. inheritance), whereas Scala focuses on the types.

Subtyping is most useful when describing the properties of some set of related values (and its subsets), and from that perspective it does not make much sense to relate the types Person and Logging—I’d rather use composition here by referencing a Logger from within each Person.

Regards,

Roland

30 jan 2016 kl. 23:27 skrev Petr Novak <[hidden email]>:

Unfortunatelly it doesn't help me or I just don\t get it. I still have to lookup on code review how Logging is implemented if it is trait or an engineer was ignorant:)

I think I have realized one possible advantage. When I change class to trait I don't have to go to every usage source code and change "with" to "extends". IDE refactoring should cover it though (I haven't tried in IDEA). Changing trait to class has high chance to break.

Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

Dimitriye Danilović-2
Extension is a single operation. But in particular, classes extend TYPES, not just other classes. `with` is an operator which takes two types and fuses them together into one. So when you do `class Thingymabob extends (Thingy with Mabob)` you're making the class `Thingymabob` which extends the type `Thingy with Mabob`. Traits are a subset of types, just like classes are a subset of types.

On Sun, Jan 31, 2016 at 12:21 AM, Roland Kuhn <[hidden email]> wrote:
It might help to realize that “with” has nothing to do with traits, and that “extends” is not so much about inheritance but about types.

rule 1: every class “extends” a type—it none is given then AnyRef is assumed
rule 2: types can be combined using “with”, creating an intersection of them (i.e. the resulting type contains all values that have the properties from all of the combined types)

Therefore it does not make sense to write class A with Logging: this would try to define “A with Logging” in terms of AnyRef, but what we really want is to define “A” in terms of “AnyRef with Logging”.

Given the following:

class Person extends Logging {
  def name: String
}

We declare a new class named Person that extends the type Logging (incidentally this means inheriting all the properties or members of this type) with a refinement that adds another property called “name” of type “String”. The most interesting part is not that Logging’s properties are inherited, but that Person is a subtype of Logging. This is a change compared to Java which focuses on which methods get pulled together on which classes (i.e. inheritance), whereas Scala focuses on the types.

Subtyping is most useful when describing the properties of some set of related values (and its subsets), and from that perspective it does not make much sense to relate the types Person and Logging—I’d rather use composition here by referencing a Logger from within each Person.

Regards,

Roland

30 jan 2016 kl. 23:27 skrev Petr Novak <[hidden email]>:

Unfortunatelly it doesn't help me or I just don\t get it. I still have to lookup on code review how Logging is implemented if it is trait or an engineer was ignorant:)

I think I have realized one possible advantage. When I change class to trait I don't have to go to every usage source code and change "with" to "extends". IDE refactoring should cover it though (I haven't tried in IDEA). Changing trait to class has high chance to break.

Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

oss.mlists
I think I have got it now, at least it makes more sense. I have to shift my understanding. The, probably higher level, design approach when to use inheritance and when composition doesn't map to extends and with. Bad thing is that even I have read quite a bit about Scala I can't remember it was discussed this way (sometimes I skip pages:)).

Actually pattern "Person with Logging" is used a lot, including prominent code like Spark and even Akka (class MetricsListener extends Actor with ActorLogging).  UntypedActors in Akka uses referencing to logger from actors though.

Should I consider "Person with Logging" an anti-pattern? Is ActorLogging a sin of the past? Or there is yet another dimension in understanding when to use what?

Huge thanks,
Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

Roland Kuhn
Hi Petr,

I should probably mention one omission in my previous post: there is a code pattern that some hate and some love, it is useful when it works well and it gets really messy when over-used—I am speaking of the cake pattern. ActorLogging fits within this mindset in that the different active aspects of this entity (it is an Actor, it does Logging, … ) are baked together to form a whole where the individual parts have some dependencies on other parts, resolved at compile time and thus checked by the compiler (as opposed to traditional dependency injection frameworks).

Having said that, I would probably not introduce ActorLogging as a trait again, it does not add much value above declaring a val log in the actor itself. We have applied the cake pattern very successfully elsewhere in the Akka internals, though.

Regards,

Roland

3 feb 2016 kl. 16:49 skrev Petr Novak <[hidden email]>:

I think I have got it now, at least it makes more sense. I have to shift my understanding. The, probably higher level, design approach when to use inheritance and when composition doesn't map to extends and with. Bad thing is that even I have read quite a bit about Scala I can't remember it was discussed this way (sometimes I skip pages:)).

Actually pattern "Person with Logging" is used a lot, including prominent code like Spark and even Akka (class MetricsListener extends Actor with ActorLogging).  UntypedActors in Akka uses referencing to logger from actors though.

Should I consider "Person with Logging" an anti-pattern? Is ActorLogging a sin of the past? Or there is yet another dimension in understanding when to use what?

Huge thanks,
Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Why trait "extends" class instead of "with" when class extends only a trait(s)?

Dimitriye Danilović-2
In reply to this post by oss.mlists
ActorLogging is a mixin. It automatically configures a logger for the Actor which it's mixed into.

On Wednesday, February 3, 2016 at 7:49:53 AM UTC-8, Petr Novak wrote:
I think I have got it now, at least it makes more sense. I have to shift my understanding. The, probably higher level, design approach when to use inheritance and when composition doesn't map to extends and with. Bad thing is that even I have read quite a bit about Scala I can't remember it was discussed this way (sometimes I skip pages:)).

Actually pattern "Person with Logging" is used a lot, including prominent code like Spark and even Akka (class MetricsListener extends Actor with ActorLogging).  UntypedActors in Akka uses referencing to logger from actors though.

Should I consider "Person with Logging" an anti-pattern? Is ActorLogging a sin of the past? Or there is yet another dimension in understanding when to use what?

Huge thanks,
Petr

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.