2

Question

Why case 2 causes "unbound placeholder parameter" while case 1 is OK?

Case 1

val h: (Int => Int) = (x:Int) => { scala.util.Random.nextInt(x) }
val _h: (Int => Int) = { scala.util.Random.nextInt(_) }
h(5)     // 3
_h(5)    // 3

Case 2

val f: (Int => Int) = (x:Int) => { x }
f(5)     // 5
// Causes error
val _f: (Int => Int) = { _ }   <----- unbound placeholder parameter
mon
  • 18,789
  • 22
  • 112
  • 205
  • 2
    There is no way `_` can be a valid `Int => Int`, whereas `scala.util.Random.nextInt(_)` is one (aka infered as `scala.util.Random.nextInt(_: Int)` or `{ i: Int => scala.util.Random.nextInt(i) }`) – cchantep Dec 03 '19 at 11:54
  • first case is lambda expression: `{ i: Int => scala.util.Random.nextInt(i) }` but in case 2 you have just empty block, it don't waiting for some arguments and don't know what to return. You can't replace by placeholder any argument of function which has empty body. – Boris Azanov Dec 03 '19 at 13:36

2 Answers2

3

_ is never interpreted as x => x in Scala.

If I understand the part of language spec where it talks about "binding underscore sections" correctly, this is precisely because Scala reserves _ for partial application. Like in case of scala.util.Random.nextInt(_) it means x => nextInt(x) and not nextInt(x => x).

Oleg Pyzhcov
  • 7,323
  • 1
  • 18
  • 30
2

.nextInt(_) is not an example of placeholder usage. In this case the underscore _ is used for "eta expansion" of the nextInt() method, i.e. promoting the method to a proper function. The result is equivalent to the following:

val _h: (Int => Int) = util.Random.nextInt

To get your _f() code to work you could do this.

val _f: (Int => Int) = identity
jwvh
  • 50,871
  • 7
  • 38
  • 64