scala - Placeholder syntax doesn't hold my place -


i have read other questions what uses of underscore in scala? , while i'm sure question has been asked, can't go through of other 17000 scala questions.

there foreach have strange behaviour , placeholder not useful still seems hidden feature:

scala> val = (1 5) tolist is: list[int] = list(1, 2, 3, 4, 5)  scala> foreach { => println("hi.") ; console println 2 * } hi. 2 hi. 4 hi. 6 hi. 8 hi. 10  scala> foreach { println("hi.") ; console println 2 * _ } hi. 2 4 6 8 10 

can explain me please difference?

if feel burst of enthusiasm , try:

scala> foreach { => println("hi!") ; console println 2 * } java.lang.illegalargumentexception: !") ; console println 2 * }: event not found 

then see this answer. , yes happened.

landei has right answer, think, it's not unpacked thoroughly. let's start @ end:

scala> console println 2 * _ <console>:8: error: missing parameter type expanded function ((x$1) => console.println(2.$times(x$1)))               console println 2 * _                                   ^ 

okay, see on own, console println 2 * _ trying create function via explicit eta expansion, except doesn't know return parameter type can't.

now let's try code block returns function.

scala> { println("hi"); (i: int) => i*5 } hi res1: int => int = <function1> 

so, everything, execute entire block (including side-effecting statements println), , return return value function.

now, landei said, placeholder syntax works 1 argument in 1 (simple) expression, , in second case don't have simple expression block expression (consisting of 2 simple expressions). we're not using placeholder syntax, we're creating function. , in code block:

is foreach { println("hi.") ; console println 2 * _ } 

which, since don't start function arguments, interpreted plain parameter, except can in context--argument lists included--replace simple expression (x) block expression { stuff; x }. can think of as

is foreach ({ println("hi.") ; console.println 2 * _ }) 

now type inferencer knows return type supposed be, runs code block prints out "hi" , creates function, passes function (just once, @ beginning!) foreach. if type inferencer across lines figure out types, equivalent this:

val temp = { println("hi."); console.println 2 * _ } foreach (temp) 

Comments