Seq :+ repeat parameter

103 views
Skip to first unread message

Rich Oliver

unread,
Apr 7, 2016, 8:45:28 AM4/7/16
to scala-language
I have created the following code and it seems to compile and run correctly:

val scaleButs = Seq(CanvButton("+", () => { scale = (scale * 1.5).min(scaleMax); repaintMap() }),
      CanvButton("-", () => { scale = (scale / 1.5).max(scaleMin); repaintMap() }))
   val mapButs = scaleButs :+ (     
      CanvButton("<=", () => { mapFocus = mapFocus.subX(moveInc); repaintMap() }),
      CanvButton("=>", () => { mapFocus = mapFocus.addX(moveInc); repaintMap() }),
      CanvButton("Up", () => { mapFocus = mapFocus.addY(moveInc); repaintMap() }),
      CanvButton("down", () => { mapFocus = mapFocus.subY(moveInc); repaintMap() })
   )

But in the API documentation the :+ doesn't have a repeat parameter. I've looked in SeqLike.scala https://github.com/scala/scala/blob/v2.11.8/src/library/scala/collection/SeqLike.scala#L1 and I can't see any repeat parameter for the :+ method there either.

Oliver Ruebenacker

unread,
Apr 7, 2016, 8:49:18 AM4/7/16
to scala-l...@googlegroups.com

     Hello,

  Is it possible that your code does not do what one might think it does?

scala> val seq = Seq(1, 2, 3)
seq: Seq[Int] = List(1, 2, 3)

scala> val seq2 = seq :+ (4, 5, 6)
seq2: Seq[Any] = List(1, 2, 3, (4,5,6))

     Best, Oliver



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



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

Dean Wampler

unread,
Apr 7, 2016, 8:52:06 AM4/7/16
to scala-l...@googlegroups.com
Do you mean that you want to add the same object multiple times with a repeat parameter? That isn't provided, but a for loop would work. 

Or do you mean chaining? You can do the following:

val scalaButs = CanvButton(...) +: CanvButton(...) +: ... +: Nil

Note I used +: You don't want to use :+ with Lists (what Seq.apply() returns), because appending is O(n). However, appending to Vectors is O(1).

val scalaButs1 = Vector(CanvButton(...))

val scalaButs = scalaButs1 :+ CanvButton(...) :+ ... :+ CanvButton(...)

--

Rich Oliver

unread,
Apr 7, 2016, 9:29:07 AM4/7/16
to scala-language
On Thursday, 7 April 2016 13:49:18 UTC+1, Oliver Ruebenacker wrote:

     Hello,

  Is it possible that your code does not do what one might think it does?

scala> val seq = Seq(1, 2, 3)
seq: Seq[Int] = List(1, 2, 3)

scala> val seq2 = seq :+ (4, 5, 6)
seq2: Seq[Any] = List(1, 2, 3, (4,5,6))

     Best, Oliver

Hi yes you're right. I was forgetting Scala's insanely hyperactive type inference. Well at least I'm not alone, it drove Paul Phillips to despair. Will this madness get worse with type unions?

Oliver Ruebenacker

unread,
Apr 7, 2016, 10:10:31 AM4/7/16
to scala-l...@googlegroups.com

     Hello,

  I'm not sure that Paul Philips was too concerned about that aspect of type inference.

  These typical code bugs that lead to references inferred as Any, AnyRef, AnyVal or Nothing are usually quite harmless: as soon as you are trying to use the reference you notice that you can't do much with it and realize quickly what is going on.

  Union types: I would assume if you have a union type A|B, you cannot call A's methods on it, but you would have to match A first. In that case, I don't see much change.

     Best, Oliver

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

Simon Schäfer

unread,
Apr 7, 2016, 10:10:56 AM4/7/16
to scala-l...@googlegroups.com
It is expected to improve the situation, since it would help to infer Seq[Int|Tuple3]. On the other hand, that is still not the expected type. If you fear type inference, just add more explicit types, that helps a lot. I wonder nevertheless how you could end up with such a programming mistake, because static analysis can easily warn about that, which is what scalac should already do for the above code (at least if you use a reasonable actual Scala version).

Naftoli Gugenheim

unread,
Apr 7, 2016, 4:56:05 PM4/7/16
to scala-language


On Thu, Apr 7, 2016, 9:29 AM Rich Oliver <rzi...@gmail.com> wrote:
On Thursday, 7 April 2016 13:49:18 UTC+1, Oliver Ruebenacker wrote:

     Hello,

  Is it possible that your code does not do what one might think it does?

scala> val seq = Seq(1, 2, 3)
seq: Seq[Int] = List(1, 2, 3)

scala> val seq2 = seq :+ (4, 5, 6)
seq2: Seq[Any] = List(1, 2, 3, (4,5,6))

     Best, Oliver

Hi yes you're right. I was forgetting Scala's insanely hyperactive type inference.

What is insane or hyperactive about this, and what does it have to do with type inference? You wrote the append operator and a tuple, dunno why you didn't see that, but no need to blame Scala.

Why not use the ++ operator?




Well at least I'm not alone, it drove Paul Phillips to despair. Will this madness get worse with type unions?

--

Rich Oliver

unread,
Apr 7, 2016, 6:44:02 PM4/7/16
to scala-language
On Thursday, 7 April 2016 21:56:05 UTC+1, nafg wrote:

What is insane or hyperactive about this, and what does it have to do with type inference? You wrote the append operator and a tuple, dunno why you didn't see that, but no need to blame Scala.

Why not use the ++ operator?

I was aware that I could use ++ "Seq"  ........ but I thought there was repeat parameter operator, allowing me to save the "Seq" characters, so I tried it. The inferred type was:

Seq[Product with Serializable with Object {..}]

I am quite happy to admit to many non trivial flaws as a developer, but I would ask when the above type or similar is inferred, what percentage of the time is their an error as opposed to the compiler inferring the programmers intention? Maybe my knowledge is incomplete but how often do people intentionally create a Seq[Product with Serializable]? Its not the end of the world for me, the pros of Scala far out weight the flaws. However when trying to persuade new people of the benefits of Scala these sorts of surprises can potentially be a deal breaker. One of our prime selling points with Scala is the early detection of type errors.

Perhaps part of the problem is that "If" and "match" expressions can not be explicitly type parametised.

Naftoli Gugenheim

unread,
Apr 7, 2016, 7:51:28 PM4/7/16
to scala-language
I agree that it would be nice to flag such types but the fact that they aren't flagged isn't the fault of the type inference, it's the lack of additional code to check the inferred type after the fact.


Perhaps part of the problem is that "If" and "match" expressions can not be explicitly type parametised.

You can use an ascription...
((...): Type)

som-snytt

unread,
Apr 14, 2016, 5:54:59 PM4/14/16
to scala-language

paulp would say, Xlint would have told you not to do that.

$ scala -Xlint
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.

scala> scala> val seq = Seq(1, 2, 3)

// Detected repl transcript. Paste more, or ctrl-D to finish.


seq: Seq[Int] = List(1, 2, 3)

scala> val seq2 = seq :+ (4, 5, 6)
seq2: Seq[Any] = List(1, 2, 3, (4,5,6))
// Replaying 2 commands from transcript.


scala> val seq = Seq(1, 2, 3)
seq: Seq[Int] = List(1, 2, 3)

scala> val seq2 = seq :+ (4, 5, 6)
<console>:12: warning: Adapting argument list by creating a 3-tuple: this may not be what you want.
        signature: SeqLike.:+[B >: A, That](elem: B)(implicit bf: scala.collection.generic.CanBuildFrom[Repr,B,That]): That
  given arguments: 4, 5, 6
 after adaptation: SeqLike.:+((4, 5, 6): (Int, Int, Int))

       val seq2 = seq :+ (4, 5, 6)
                      ^

seq2: Seq[Any] = List(1, 2, 3, (4,5,6))


scala> :quit

I suppose it suppresses -Ywarn-infer-any, or no it doesn't actually warn for the previous example.

scala> List(1, "abc")
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error.
Reply all
Reply to author
Forward
0 new messages