136

In Scala, is there any difference at all between Nil and List()?

If not, which one is more idiomatic Scala style? Both for creating new empty lists and pattern matching on empty lists.

3 Answers 3

198
scala> println (Nil == List())
true

scala> println (Nil eq List())
true

scala> println (Nil equals List())
true

scala> System.identityHashCode(Nil)
374527572

scala> System.identityHashCode(List())
374527572

Nil is more idiomatic and can be preferred in most cases. Questions?

11
  • 11
    You could mention that Nil is more idiomatic.
    – Rex Kerr
    Commented May 12, 2011 at 17:30
  • 6
    Added System.identityHashCode to clarify what "eq" already says - they're the same object.
    – James Iry
    Commented May 12, 2011 at 18:08
  • 20
    Besides, Nil references an object directly, whereas List() is a method call. Commented May 12, 2011 at 21:07
  • 6
    Isn't List[A]() (not Nil) necessary as an accumulator value for foldLeft? Example - scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world) Using Nil as the accumulator here wouldn't work. Commented Nov 17, 2013 at 4:57
  • 6
    Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
    – Arneball
    Commented Feb 23, 2015 at 18:03
88

User unknown has shown that the run time value of both Nil and List() are the same. However, their static type is not:

scala> val x = List()
x: List[Nothing] = List()

scala> val y = Nil
y: scala.collection.immutable.Nil.type = List()

scala> def cmpTypes[A, B](a: A, b: B)(implicit ev: A =:= B = null) = if (ev eq null) false else true
cmpTypes: [A, B](a: A, b: B)(implicit ev: =:=[A,B])Boolean

scala> cmpTypes(x, y)
res0: Boolean = false

scala> cmpTypes(x, x)
res1: Boolean = true

scala> cmpTypes(y, y)
res2: Boolean = true

This is of particular importance when it is used to infer a type, such as in a fold's accumulator:

scala> List(1, 2, 3).foldLeft(List[Int]())((x, y) => y :: x)
res6: List[Int] = List(3, 2, 1)

scala> List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
<console>:10: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Nil.type
       List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
                                               ^
2
  • i do not understand why 2::Nil works but not fold's accumulator y::x
    – FUD
    Commented Jan 4, 2013 at 8:20
  • 2
    @FUD Well, y :: x does work. The problem is that the type it returns is not the type expected. It returns List[Int], while the type expected is either List[Nothing] or Nil.type (I think the former, but maybe the latter). Commented Jan 6, 2013 at 2:57
29

As user unknown's answer shows, they are the same object.

Idiomatically Nil should be preferred because it is nice and short. There's an exception though: if an explicit type is needed for whatever reason I think

List[Foo]() 

is nicer than

Nil : List[Foo]
1
  • 40
    There's also List.empty[Foo] as a third alternative.
    – kassens
    Commented May 13, 2011 at 0:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.