Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird stuff with curried function

I have this weird situation that I don't understand. I'm reading "Programming in Scala" book, Ch. 9.

Let's say I have a curried function:

def withThis(n:Int)(op:Int=>Unit){
      println("Before")
      op(n);
      println("After")
}

When I call it with one argument inside a special curly-syntax it works as expected:

withThis(5){
   (x) => {println("Hello!"); println(x); }
}
// Outputs
Before
Hello!
5
After

However, if I put two statements, I get something wierd:

withThis(5){
     println("Hello!")
     println(_)
}
// Outputs
Hello!
Before
5
After

How come the "Hello!" gets printed before "Before" and then "5" is printed inside? Am I crazy?

like image 978
Andriy Drozdyuk Avatar asked Apr 28 '11 17:04

Andriy Drozdyuk


2 Answers

Your last code example should be rewritten as follows to produce the expected result:

withThis(5) { x =>
     println("Hello!")
     println(x)
}

Otherwise, your example is equivalent to

withThis(5) {
     println("Hello!")
     (x: Int) => println(x)
}

as the placeholder _ will be expanded to bind as tightly as possible in a non-degenerated way (i.e., it wouldn't expand to println(x => x)).

The other thing to note is that a block always returns its last value. In your example, the last value is actually (x: Int) => println(x).

like image 124
Jean-Philippe Pellet Avatar answered Oct 13 '22 05:10

Jean-Philippe Pellet


In your second example the part in curlies: { println("Hello!"); println(_) } is a block which prints "Hello!" and returns a curried println. Imagine it simplified as { println("Hello!"); 5 }, a block which prints "Hello!" and returns 5.

like image 33
Ben Jackson Avatar answered Oct 13 '22 06:10

Ben Jackson