What does _ :: mean in Scala?
Asked Answered
D

3

7

I am going through a book Lift in action and I encountered something I don't quite understand: _ ::

object permanent_link extends MappedString(this, 150){
    override def validations =
    valMinLen(3, "Link URL must be at least 5 characters") _ ::
    super.validations
}

I can't find any hint so I would be grateful if anyone could help me out..

Delict answered 10/1, 2012 at 18:33 Comment(0)
F
18

I don't know Lift, but this is a general question. First of all, the :: is a Scala cons operator:

scala> 1 :: 2 :: List(3, 4)
res0: List[Int] = List(1, 2, 3, 4)

This means that super.validations is some sort of a sequence and valMinLen(3, "Link URL must be at least 5 characters") _ is a single value in that list.

From the context it looks obvious that in overridden validations method they are calling super version and prepend some extra validation at the beginning.

This extra validation is created by a call to valMinLen(). However this extra call does not return an element matching the type of validations list - but a function. Instead of prepending the function value we are explicitly saying (by adding _ suffix`) that we want to prepend a function itself, not a return value of that function.

Code snippet is worth a thousand words:

scala> def f = 3
f: Int

scala> def g = 4
g: Int

scala> val listOfInts = List(f, g)
listOfInts: List[Int] = List(3, 4)

scala> val listOfFunctions = List(f _, g _)
listOfFunctions: List[() => Int] = List(<function0>, <function0>)

Compare the type of listOfInts and listOfFunctions. I believe the f _ syntax is called partially applied function in Scala world.

Farflung answered 10/1, 2012 at 18:42 Comment(0)
F
5

The underscore ignifies that valMinLen isn't to be called but be used as a function "pointer".

The :: operator concatenates lists.

It would in other words seem like the code builds a list validations that consist of a function "pointer" to valMinLen with the parameters given and the rest of the list is the value of super.validations, that is the super class' validations.

I'm sure someone will correct my terminology here :)

Fermentation answered 10/1, 2012 at 18:44 Comment(0)
N
0

The code might be more readable with some proper indentation and introducing a val:

object permanent_link extends MappedString(this, 150) {

  override def validations = minimumValidation :: super.validations

  val minimumValidation = valMinLen(3,"Link URL must be at least 5 characters") _
}

So as noted before, the :: operator just prepends a new element to a list, the _ has nothing to do with it and is used to obtain a function object, like in

(1 :: 2 :: Nil) map (println _)

which makes a list [1, 2] and applies the function println to every element (the underscore can actually be omitted here). The object println _ constructs a function object from the println method with the _ representing the function's single parameter.

Nebo answered 11/1, 2012 at 10:48 Comment(2)
So you can reference minimumValidation before you have declared it?Christopherchristopherso
Declaration order does not matter in scala, it doesn't in most current languages.Nebo

© 2022 - 2024 — McMap. All rights reserved.