What does the ++: operator do to a list?
Asked Answered
S

4

5

Alright, Scala has me feeling pretty dense. I'm finding the docs pretty impenetrable -- and worse, you can't Google the term "Scala ++:" because Google drops the operator terms!

I was reading some code and saw this line:

Seq(file) ++: children.flatMap(walkTree(_))  

But couldn't figure it out. The docs for Seq show three things:

++
++:
++:  

Where the latter two are over loaded to do.. something. The actual explanation in the doc says that they do the same thing as ++. Namely, add one list to another.

So, what exactly is the difference between the operators..?

Sacristy answered 21/6, 2014 at 3:59 Comment(2)
Use symbolhound to search symbols like that.Retroflex
Google is fixed now! I came here by a search for Scala ++:. :-)Whirly
G
15

++ and ++: return different results when the operands are different types of collection. ++ returns the same collection type as the left side, and ++: returns the same collection type as the right side:

scala> List(5) ++ Vector(5)
res2: List[Int] = List(5, 5)

scala> List(5) ++: Vector(5)
res3: scala.collection.immutable.Vector[Int] = Vector(5, 5)

There are two overloaded versions of ++: solely for implementation reasons. ++: needs to be able to take any TraversableOnce, but an overloaded version is provided for Traversable (a subtype of TraversableOnce) for efficiency.

Griselgriselda answered 21/6, 2014 at 5:8 Comment(0)
R
5

Just to make sure:

A colon (:) in the end of a method name makes the call upside-down.

Let's make two methods and see what's gonna happen:

object Test {
  def ~(i: Int) = null
  def ~:(i: Int) = null //putting ":" in the tail!

  this ~ 1   //compiled
  1 ~: this  //compiled
  this.~(1)  //compiled
  this.~:(1) //compiled.. lol

  this ~: 1  //error
  1 ~ this   //error
}

So, in seq1 ++: seq2, ++: is actually the seq2's method.

edited: As @okiharaherbst mentions, this is called as right associativity.

Raucous answered 21/6, 2014 at 9:20 Comment(0)
G
1

Scala function naming will look cryptic unless you learn a few simple rules and their precedence.

In this case, a colon means that the function has right associativity as opposed to the more usual left associativity that you see in imperative languages.

So ++: as in List(10) ++: Vector(10) is not an operator on the list but a function called on the vector even if it appears on its left hand-side, i.e., it is the same as Vector(10).++:(List(10)) and returns a vector.

++ as in List(10) ++ Vector(10) is now function called on the list (left associativity), i.e., it is the same as List(10).++(Vector(10)) and returns a list.

Ghoul answered 21/6, 2014 at 12:43 Comment(1)
This right-associativity can be very confusing when you combine it into ++:=: https://mcmap.net/q/1920929/-why-is-the-operator-in-the-scala-language-so-strange/14955Whirly
B
0

what exactly is the difference between the operators..?

The kind of list a Seq.++ operates on.

def ++[B](that: GenTraversableOnce[B]): Seq[B]
def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Seq[A], B, That]): That
def ++:[B](that: TraversableOnce[B]): Seq[B]

As commented in "What is the basic collection type in Scala?"

Brade answered 21/6, 2014 at 4:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.