Question about Scala's Iterable: why concat '++' but no append ':+' operator?

1,995 views
Skip to first unread message

Ben Hutchison

unread,
Jul 18, 2012, 8:27:20 PM7/18/12
to scala...@googlegroups.com
Does anyone know why Scala's Iterable trait offers a concat operator
++ between 2 Iterables, but no append or prepend :+ / +:operators
adding a single element?

Obviously, you can implement append & prepend in terms of concat,
using a wrapper List. Generally, Scala's APIs are not minimalist and
try to offer most convenient operations. So there must be some kind of
design rationale behind this decision, I'd guess.

Append and prepend of elements are offered one level lower at Seq. But
in Java interop situations, I often seem to end up with Iterables, not
Seqs.

http://www.scala-lang.org/api/current/scala/collection/Iterable.html

-Ben

Lachlan O'Dea

unread,
Jul 18, 2012, 11:48:59 PM7/18/12
to scala...@googlegroups.com
My guess is that it's because the concepts of append and prepend don't make sense for all Iterables. But then a similar objection holds for ++. The Iterable docs for ++ say "Returns a new immutable iterable collection containing the elements from the left hand operand followed by the elements from the right hand operand." But it is trivial to show that is not actually true for all Iterables:

scala> val s1: Iterable[Int] = Set(1,2,3)
s1: scala.collection.immutable.Iterable[Int] = Set(1, 2, 3)

scala> val s2: Iterable[Int] = Set(2,4)
s2: scala.collection.immutable.Iterable[Int] = Set(2, 4)

scala> s1 ++ s2
res13: scala.collection.immutable.Iterable[Int] = Set(1, 2, 3, 4)

If the standard is that we're happy with an Iterable.++ with such differences in behavior, I can see no reason not to also have an Iterable.+ to "add a single element... somewhere... maybe". Set already has +, and for List it would be prepend.

The issue with Java interop is that use of java.util.Collection is pretty common, and the only sensible choice for Scala conversion is Iterable.

Ben Hutchison

unread,
Jul 19, 2012, 3:23:34 AM7/19/12
to scala...@googlegroups.com
On Thu, Jul 19, 2012 at 1:48 PM, Lachlan O'Dea <lo...@me.com> wrote:
> Iterable docs for ++ say "Returns a new immutable iterable collection
> containing the elements from the left hand operand followed by the elements
> from the right hand operand." But it is trivial to show that is not actually
> true for all Iterables:
>
> scala> val s1: Iterable[Int] = Set(1,2,3)
> s1: scala.collection.immutable.Iterable[Int] = Set(1, 2, 3)
>
> scala> val s2: Iterable[Int] = Set(2,4)
> s2: scala.collection.immutable.Iterable[Int] = Set(2, 4)
>
> scala> s1 ++ s2
> res13: scala.collection.immutable.Iterable[Int] = Set(1, 2, 3, 4)

Lachlan, thanks for your comments.

I think "contains" has to be interpreted in the context of Sets here,
and so ++ has honored its documented behaviour in that aspect. But WRT
the LHS "followed by" the RHS, that's kind of an undefined concept for
Iterables generally, so the docs are a bit slippery there.

>
> If the standard is that we're happy with an Iterable.++ with such
> differences in behavior, I can see no reason not to also have an Iterable.+
> to "add a single element... somewhere... maybe". Set already has +, and for
> List it would be prepend.

Yeah, + makes sense. It doesn't imply an append vs prepend , just that
the result includes the new element somewhere. Seqs could interpret +
in whatever way was most convenient: eg prepend for linked lists,
append for array buffers.

-Ben
Reply all
Reply to author
Forward
0 new messages