5

Have a look at these scala snippets: if we have something like this:

List(List(1, 2), List(3, 4), List(5)) map (x => (x.size))

we can shorten it to:

List(List(1, 2), List(3, 4), List(5)) map ((_.size))

but, if we have something like this:

List(List(1, 2), List(3, 4), List(5)) map (x => (x.size, x.size))

why can't we shorten it to:

List(List(1, 2), List(3, 4), List(5)) map ((_.size, _.size))

?

GA1
  • 1,568
  • 2
  • 19
  • 30

2 Answers2

5

An amount of placeholders should be equals amount of function parameters. In your case map has 1 parameter that's why you can't use two placeholders.

Sergii Lagutin
  • 10,561
  • 1
  • 34
  • 43
  • Please, give me an example where I could end up with `map ((_.size, _.size))` on the right side of the expression. – GA1 Jun 02 '16 at 10:36
  • 1
    @GA1 You can't use 2 placeholders with `map` method. Example of usage of 2 placeholders `List(1,2,3,4).reduce(_ + _)` - sum list elements. – Sergii Lagutin Jun 02 '16 at 10:44
  • Anyway, I really enjoyed the answer to this question http://stackoverflow.com/questions/25763400/motivation-for-scala-underscore-in-terms-of-formal-language-theory-and-good-styl Especially the part with a reference to linguistics. I still don't understand why the compiler does not allow: `List(List(1, 2), List(3, 4), List(5)) map ((_.size, _.size))` What is the underlying principle for it? What "danger" would this feature bring along? – GA1 Jun 02 '16 at 12:24
  • 1
    @GA1 What would `List(List(1, 2), List(3, 4), List(5)) map ((_.size, _.size))` do? `map` takes an one operand of type `List[Int]`. – Yuval Itzchakov Jun 02 '16 at 13:54
  • I would like it to return the same result as: `List(List(1, 2), List(3, 4), List(5)) map (x => (x.size, x.size))` – GA1 Jun 02 '16 at 14:09
  • 2
    @GA1 There isn't a way to do that in Scala. It's not do to "danger"; it's due to how _ works for function shorthand. An underscore can only be used once in the body per parameter. To get the equivalent of (_.size, _.size) you have to use the full function signature or map to _.size and transform the resulting list into tuples with duplicate entries. – eques Jul 07 '16 at 14:14
2

Because List(List(1, 2), List(3, 4), List(5)) map ((_.size, _.size)) has a different meaning, namely

List(List(1, 2), List(3, 4), List(5)) map ((x => x.size, y => y.size))

(you can see this from the error message). This obviously doesn't compile, because map doesn't accept a tuple of two functions.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487