This usage of underscore is known as Placeholder Syntax for Anonymous Functions:
Such an expression represents an anonymous function where subsequent
occurrences of underscores denote successive parameters.
Note each underscore refers to different parameter so for example
_ + _
expands to
(x1, x2) => x1 + x2
Also expression _ + _ makes use of point-free syntax as opposed to
_.+(_)
for example
List("Steve", "Tom", "John", "Bob").reduce((x1: String, x2: String) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce((x1, x2) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_.+(_)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_ + _) // : String = "SteveTomJohnBob"
so now it should be clearer why expression _.compareTo(_) < 0 works
List("Steve", "Tom", "John", "Bob").sortWith(_.compareTo(_) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")
List("Steve", "Tom", "John", "Bob").sortWith((x1, x2) => x1.compareTo(x2) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")
Another way to see this let's type-ascribe the sugared expression
scala> (_.compareTo(_) < 0): ((String, String) => Boolean)
val res0: (String, String) => Boolean = $Lambda$7865/418832725@18987bf5
sortWithis notcompareTo, but the lambda_.compareTo(_) < 0. - BergicompareTo? On a magic object created out of no where? No, you are calling it in the object passed as the first argument of the function. If we remove the sugar syntax of the_syntax it should be clear:_.compareTo(_)is equivalent to(a1, a2) => a1.compareTo(a2)so you can clearly see you have a two arguments function :) - Luis Miguel Mejía Suárez