Wat? Scala

As I got quoted recently in “Scala — 1★ Would Not Program Again” I though I finally should write up a little Wat moment we had recently:

So does anyone know “wat” the following Scala code returns? (Value and Type)


A Set<Int> containing 1,2,3?

Nope how about I give you a clue, there are 2 bugs in this one line:

  1. A type inferencing bug where it chooses Set<Any>
  2. A bug where the brackets are used for both calling the Set.apply method and constructing Unit, notice there no space between the “toSet” and “()”

Yup you guessed it, it returns:


Wat? Try it in your repl and for even more fun check the bytecode out.

Looks like (“-Yno-adapted-args”, “Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.”) is your friend

Pete Kneller has done some really good analysis so you can see all the different weird combinations

11 thoughts on “Wat? Scala”

  1. Not sure what type inferencing bug you are referring to, but for me (2.9.2) this returns a Set[Int]:

    res3: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

    Also List(1,2,3).toSet() isn’t a bug. “toSet” is defined as “def toSet” since it does not have any side effects. It’s not the clearest feature but I don’t think it’s a bug.

  2. The idiomatic call works just fine:
    scala> List(1,2,3).toSet
    res2: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

    just don’t clutter your code with unnecessary parantheses.

    What has happend here?

    1. there is no method “toSet()” defined on List just “toSet”
    2. What you did was call
    3. The apply method of a set returns true if the element you call for exists i the set
    4. () can’t exist

  3. Hideous behaviour, I don’t want to make excuses for it. Just wanted to point out that adding the -Yno-adapted-args to the scalacOptions property will prevent this from happening.

  4. Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21).
    Type in expressions to have them evaluated.
    Type :help for more information.

    scala> List(1,2,3).toSet()
    :8: warning: Adapting argument list by inserting (): this is unlikely to be what you want.
    signature: GenSetLike.apply(elem: A): Boolean
    given arguments:
    after adaptation: GenSetLike((): Unit)
    res0: Boolean = false

    It’s not like it doesn’t warn you that bad things are happening.

  5. -Yno-adapted-args

    Thanks that’s really good to know, hopefully they will remove this behaviour completely real soon.

  6. Hi Dan,

    nice post! It’s an issue with auto-tupling, where the compiler tries to be too helpful.

    The toSet method doesn’t take any parameters, so the compiler assumes that you must have meant to call the apply method of Set, and that method returns a Boolean.

    So what the compiler understands looks more like

    Some discussions about this on the mailing list: https://groups.google.com/d/topic/scala-internals/4RMEZGObPm4/discussion https://groups.google.com/d/topic/scala-debate/zwG8o2YzCWs/discussion

    If everything works out, we can hopefully get rid of it for 2.11. :-)



  7. x and x() are different signatures in scala, and the convention is that you use x() for things that have side effects. but that’s not even massively relevant here, just rtfm.

  8. Seems you only need -deprecation to avoid the issue. Even without the -deprecation, you get a warning which is nice.

    The 1-star blog you point to is a ridiculous rant from someone who used Scala for a couple of weeks and wasn’t taken by the syntax use or use of types. Obviously coming from a Ruby or JS type of background.

    How about yourself, what programming languages are you into at the moment?

Leave a Reply

Your email address will not be published. Required fields are marked *