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

Re: Collections in 2.8: Why extends the collection traits their implementation traits (and not the other way round)?

3 replies
Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 3 days ago.

Hard to comment without knowing your exact use-case
but... you can happily use for-comprehensions on Option, which might
take away some of your pain.

On Thu, Oct 22, 2009 at 10:33 AM, Stefan Wachter wrote:
> Hi Kevin,
>
> thanks for the suggestion.
>
> In fact Option implements many of the methods that you find at Traversable,
> but unfortunately it is not derived from Traversable. If you want to use an
> Option as a Traversable in a method call then (afaik) it would be possible
> only by a structural type with its negative performance impact.
>
> I think it would be nice to have Option mixing in Traversable. But it seems
> to make not much sense that Options inherits the implementation from
> TraversableLike. This illustrates the point I tried to make with my original
> post.
>
> Cheers,
> --Stefan
>
>
>
> Kevin Wright wrote:
>
> Your best bet if you want a "SingleTraversable" is to use Option, it
> has the full compliment of map/flatmap/foreach methods that you'll be
> needing
>
> On Thu, Oct 22, 2009 at 9:32 AM, Stefan Wachter
> wrote:
>
>
> Hi all,
>
> I took a closer look on the collections in 2.8 and read the SID for
> collections (http://www.scala-lang.org/sids).
>
> Having my (basic) OO knowledge in mind I expected to find pure abstract
> traits (i.e. interfaces) that describe the basic kinds of collections. Then
> these interfaces would be implemented somehow.
>
> Yet, what I found were traits that stand for certain collection concepts
> (like Traversable or Iterable) that inherit lots of implementation code from
> so called template traits (named TraversableLike or IterableLike,
> respectively) and do not add any further aspects.
>
> I think that this design can make custom implementations of collections more
> difficult.
>
> For example if I want to develop a trait that allows to view single
> instances as traversables with a single member then I must look really
> carefully at the TraversableLike trait and watch out for all methods that
> should be handled differently. For example TraversableLike implements the
> isEmpty method by:
>
> def isEmpty: Boolean = {
>  var result = true
>  breakable {
>   for (x <- this) {
>     result = false
>     break
>   }
>  }
>  result
> }
>
> Clearly, a "SingleTraversable" can do better:
>
> override def isEmpty: Boolean = false
>
> If the TraversableLike trait changes in future I might miss some of the
> methods that should be overriden and fallback on inefficient
> implementations.
>
> Therefore I think that it would be better to have pure abstract collection
> traits that have to be implemented.
>
> Cheers,
>
> --Stefan
>
> PS: Is there more material available for the new 2.8 collections?
>
>
>
>
>
>

Donna Malayeri
Joined: 2009-10-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Collections in 2.8: Why extends the collection traits thei
Adriaan thinks it would be nice to have an "extendsInterface"-like keyword, where you get the interface of a type, but not its implementation. Then you could say that you implement the implicit interface of these traits that contain code, and you would not get any default implementations.

Donna

On Thu, Oct 22, 2009 at 11:48 AM, Kevin Wright <kev [dot] lee [dot] wright [at] googlemail [dot] com> wrote:
Hard to comment without knowing your exact use-case
but... you can happily use for-comprehensions on Option, which might
take away some of your pain.


On Thu, Oct 22, 2009 at 10:33 AM, Stefan Wachter <Stefan [dot] Wachter [at] gmx [dot] de> wrote:
> Hi Kevin,
>
> thanks for the suggestion.
>
> In fact Option implements many of the methods that you find at Traversable,
> but unfortunately it is not derived from Traversable. If you want to use an
> Option as a Traversable in a method call then (afaik) it would be possible
> only by a structural type with its negative performance impact.
>
> I think it would be nice to have Option mixing in Traversable. But it seems
> to make not much sense that Options inherits the implementation from
> TraversableLike. This illustrates the point I tried to make with my original
> post.
>
> Cheers,
> --Stefan
>
>
>
> Kevin Wright wrote:
>
> Your best bet if you want a "SingleTraversable" is to use Option, it
> has the full compliment of map/flatmap/foreach methods that you'll be
> needing
>
> On Thu, Oct 22, 2009 at 9:32 AM, Stefan Wachter <Stefan [dot] Wachter [at] gmx [dot] de>
> wrote:
>
>
> Hi all,
>
> I took a closer look on the collections in 2.8 and read the SID for
> collections (http://www.scala-lang.org/sids).
>
> Having my (basic) OO knowledge in mind I expected to find pure abstract
> traits (i.e. interfaces) that describe the basic kinds of collections. Then
> these interfaces would be implemented somehow.
>
> Yet, what I found were traits that stand for certain collection concepts
> (like Traversable or Iterable) that inherit lots of implementation code from
> so called template traits (named TraversableLike or IterableLike,
> respectively) and do not add any further aspects.
>
> I think that this design can make custom implementations of collections more
> difficult.
>
> For example if I want to develop a trait that allows to view single
> instances as traversables with a single member then I must look really
> carefully at the TraversableLike trait and watch out for all methods that
> should be handled differently. For example TraversableLike implements the
> isEmpty method by:
>
> def isEmpty: Boolean = {
>  var result = true
>  breakable {
>   for (x <- this) {
>     result = false
>     break
>   }
>  }
>  result
> }
>
> Clearly, a "SingleTraversable" can do better:
>
> override def isEmpty: Boolean = false
>
> If the TraversableLike trait changes in future I might miss some of the
> methods that should be overriden and fallback on inefficient
> implementations.
>
> Therefore I think that it would be better to have pure abstract collection
> traits that have to be implemented.
>
> Cheers,
>
> --Stefan
>
> PS: Is there more material available for the new 2.8 collections?
>
>
>
>
>
>

Kieron Wilkinson
Joined: 2009-03-11,
User offline. Last seen 42 years 45 weeks ago.
RE: Collections in 2.8: Why extends the collection traits thei
I think that the original poster was talking about implementing things in terms of TraversableLike. Since TraversableLike seems to implement map() for you in terms of foreach(), as does everything else, I thought the only think *required* in that case is foreach()... well, that and a builder/CanBuildFrom. That is why I said I thought everything else was just optimisations.   If you are not using TraversableLike or other trait, then yes, I understand that you need to implement foreach, map, flatMap and filter to get something more useful in for-loops. Nice run-down though, it's can't be said often enough. :)   Kieron
From: Kevin Wright <kev [dot] lee [dot] wright [at] googlemail [dot] com> [mailto:Kevin Wright <kev [dot] lee [dot] wright [at] googlemail [dot] com>]
Sent: 22 October 2009 11:31
To: Kieron [dot] Wilkinson [at] paretopartners [dot] com
Cc: scala-debate [at] listes [dot] epfl [dot] ch
Subject: Re: [scala-debate] Collections in 2.8: Why extends the collection traits their implementation traits (and not the other way round)?

not quite...
foreach is used when all the behaviour of your traversal will be via
side-effects
(println is a good example of this, a call to println doesn't return anything)

map is used when you want to convert each element to something else
and store it in a new container

so an expression like
for(x <- myCollection) yield x.someProperty
will be compiled as
myCollection.map(x -> x.someProperty)

but if you leave out the yield and rely on side effects:
for(x <- myCollection) println(x.someProperty)
then it becomes
myCollection.foreach(x -> println(x.someProperty))

flatMap gets used with more complex for-comprehensions


So...
If you're only using the yield form, you need to implement map and flatMap
If you're never using the yield form, then you only need foreach
Generally it's good practice to implement all three methods.


On Thu, Oct 22, 2009 at 11:06 AM, wrote:
> Isn't the basic idea that you can simply implement foreach() in your custom
> collection, and implementing other methods is just for optimisation? If so,
> I think that is pretty good as far as a collection library goes. :-)
>
> Kieron
>
> ________________________________
> From: Stefan Wachter [mailto:Stefan Wachter
> ]
> Sent: 22 October 2009 09:32
> To: scala-debate [at] listes [dot] epfl [dot] ch
> Subject: [scala-debate] Collections in 2.8: Why extends the collection
> traits their implementation traits (and not the other way round)?
>
> Hi all,
>
> I took a closer look on the collections in 2.8 and read the SID for
> collections (http://www.scala-lang.org/sids).
>
> Having my (basic) OO knowledge in mind I expected to find pure abstract
> traits (i.e. interfaces) that describe the basic kinds of collections.
> Then these interfaces would be implemented somehow.
>
> Yet, what I found were traits that stand for certain collection concepts
> (like Traversable or Iterable) that inherit lots of implementation code
> from so called template traits (named TraversableLike or IterableLike,
> respectively) and do not add any further aspects.
>
> I think that this design can make custom implementations of collections
> more difficult.
>
> For example if I want to develop a trait that allows to view single
> instances as traversables with a single member then I must look really
> carefully at the TraversableLike trait and watch out for all methods
> that should be handled differently. For example TraversableLike
> implements the isEmpty method by:
>
> def isEmpty: Boolean = {
> var result = true
> breakable {
> for (x < - this) {
> result = false
> break
> }
> }
> result
> }
>
> Clearly, a "SingleTraversable" can do better:
>
> override def isEmpty: Boolean = false
>
> If the TraversableLike trait changes in future I might miss some of the
> methods that should be overriden and fallback on inefficient
> implementations.
>
> Therefore I think that it would be better to have pure abstract
> collection traits that have to be implemented.
>
> Cheers,
>
> --Stefan
>
> PS: Is there more material available for the new 2.8 collections?
>
>
>
> Information Classification: Public
>
> This message may contain confidential and privileged information and is
> intended solely for the use of the named addressee. Access, copying or
> re-use of the e-mail or any information contained therein by any other
> person is not authorised. If you are not the intended recipient please
> notify us immediately by returning the e-mail to the originator and then
> immediately delete this message. Although we attempt to sweep e-mail and
> attachments for viruses, we do not guarantee that either are virus-free and
> accept no liability for any damage sustained as a result of viruses.
>
> Please refer to http://www.bnymellon.com/disclaimer/piml.html for certain
> disclosures.
>

This message may contain confidential and privileged information and is intended solely for the use of the named addressee. Access, copying or re-use of the e-mail or any information contained therein by any other person is not authorised. If you are not the intended recipient please notify us immediately by returning the e-mail to the originator and then immediately delete this message. Although we attempt to sweep e-mail and attachments for viruses, we do not guarantee that either are virus-free and accept no liability for any damage sustained as a result of viruses.

Please refer to http://www.bnymellon.com/disclaimer/piml.html for certain disclosures.
Stefan Wachter
Joined: 2009-09-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Collections in 2.8: Why extends the collection traits thei
Hi Donna & Kevin,

I think "extendsInterface" would do the job. Yet, I think the better solution would be to have pure abstract traits (i.e. interfaces) at the top of the collection hierarchy.

If I have a concrete implementation of a Traversable then I could either choose to extend TraversableLike (and inherit all its implementation) or I could choose to extends Traversable (which would not extend TraversableLike) and implement everything myself.

Maybe it would be possible to make TraversableLike more granular, i.e. split it into serveral implementation traits. One trait could be responsible for map, flatMap, and filter. Then a concrete traversable could decide which parts of the implementation it wants to reuse.

I must admit that my understanding of the collection library is not very deep. But I have the feeling, that the design of the collection library is strongly driven by "implementation inheritance". I do not understand why this way was choosen because traits would allow to mixin implementations flexibly into the concrete classes.

Cheers,
--Stefan




Donna Malayeri wrote:
a18479010910220303j1f5bf98q3e0a2a86423698d0 [at] mail [dot] gmail [dot] com" type="cite">Adriaan thinks it would be nice to have an "extendsInterface"-like keyword, where you get the interface of a type, but not its implementation. Then you could say that you implement the implicit interface of these traits that contain code, and you would not get any default implementations.

Donna

On Thu, Oct 22, 2009 at 11:48 AM, Kevin Wright <kev [dot] lee [dot] wright [at] googlemail [dot] com" rel="nofollow">kev [dot] lee [dot] wright [at] googlemail [dot] com> wrote:
Hard to comment without knowing your exact use-case
but... you can happily use for-comprehensions on Option, which might
take away some of your pain.


On Thu, Oct 22, 2009 at 10:33 AM, Stefan Wachter <Stefan [dot] Wachter [at] gmx [dot] de" rel="nofollow">Stefan [dot] Wachter [at] gmx [dot] de> wrote:
> Hi Kevin,
>
> thanks for the suggestion.
>
> In fact Option implements many of the methods that you find at Traversable,
> but unfortunately it is not derived from Traversable. If you want to use an
> Option as a Traversable in a method call then (afaik) it would be possible
> only by a structural type with its negative performance impact.
>
> I think it would be nice to have Option mixing in Traversable. But it seems
> to make not much sense that Options inherits the implementation from
> TraversableLike. This illustrates the point I tried to make with my original
> post.
>
> Cheers,
> --Stefan
>
>
>
> Kevin Wright wrote:
>
> Your best bet if you want a "SingleTraversable" is to use Option, it
> has the full compliment of map/flatmap/foreach methods that you'll be
> needing
>
> On Thu, Oct 22, 2009 at 9:32 AM, Stefan Wachter <Stefan [dot] Wachter [at] gmx [dot] de" rel="nofollow">Stefan [dot] Wachter [at] gmx [dot] de>
> wrote:
>
>
> Hi all,
>
> I took a closer look on the collections in 2.8 and read the SID for
> collections (http://www.scala-lang.org/sids).
>
> Having my (basic) OO knowledge in mind I expected to find pure abstract
> traits (i.e. interfaces) that describe the basic kinds of collections. Then
> these interfaces would be implemented somehow.
>
> Yet, what I found were traits that stand for certain collection concepts
> (like Traversable or Iterable) that inherit lots of implementation code from
> so called template traits (named TraversableLike or IterableLike,
> respectively) and do not add any further aspects.
>
> I think that this design can make custom implementations of collections more
> difficult.
>
> For example if I want to develop a trait that allows to view single
> instances as traversables with a single member then I must look really
> carefully at the TraversableLike trait and watch out for all methods that
> should be handled differently. For example TraversableLike implements the
> isEmpty method by:
>
> def isEmpty: Boolean = {
>  var result = true
>  breakable {
>   for (x <- this) {
>     result = false
>     break
>   }
>  }
>  result
> }
>
> Clearly, a "SingleTraversable" can do better:
>
> override def isEmpty: Boolean = false
>
> If the TraversableLike trait changes in future I might miss some of the
> methods that should be overriden and fallback on inefficient
> implementations.
>
> Therefore I think that it would be better to have pure abstract collection
> traits that have to be implemented.
>
> Cheers,
>
> --Stefan
>
> PS: Is there more material available for the new 2.8 collections?
>
>
>
>
>
>


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