Nil is basic building block for creating List as a recursive data structure. List is useful datastructure that provides constant time access O(1) to the head (first element).
List at it's bare minimum core, is built on top of 3 operations
head, tail, and isEmpty. Nil is singleton sub-class of List, so it is a special one-of-its-kind instance representing an empty list. The cons operator :: is defined on List to build a list recursively, by prepending one element in the List.
See the definition of trait List and object Nil (highly simplified)
trait List[A] {
def head: A
def tail: List[A]
def isEmpty: Boolean
}
case object Nil extends List[Nothing] {
def head = throw new NoSuchElementException("head of empty list")
def tail = throw new UnsupportedOperationException("tail of empty list")
def isEmpty = true
}
Since any identifier/operator that ends with a :, associates to the right, :: operator also associates to the right.
When you write 1::2::3, scala tries to rewrite this calls as 3.::(2.::(1)). i.e 3 becomes the receiver of the first invocation of ::, which doesn't exist on any arbitrary data-type (Int in this case).
This is why, you always build up on an Empty List - Nil. Think of it as prepending each element, one by one over the empty List Nil.