0

The Scala Tour Of Scala docs explain pass-by-name parameters using a whileLoop function as an example.

def whileLoop(condition: => Boolean)(body: => Unit): Unit =
  if (condition) {
    body
    whileLoop(condition)(body)
  }

var i = 2

whileLoop (i > 0) {
  println(i)
  i -= 1
}  // prints 2 1

The section explains that if the condition is not met then the body is not evaluated, thus improving performance by not evaluating a body of code that isn't being used.

Does Scala's implementation of while already use pass-by-name parameters?

If there's a reason or specific cases where it's not possible for the implementation to use pass-by-name parameters, please explain to me, I haven't been able to find any information on it so far.

EDIT: As per Valy Dia's (https://stackoverflow.com/users/5826349/valy-dia) answer, I would like to add another question...

Would a method implementation of the while statement perform better than the statement itself if it's possible not to evaluate the body at all for certain cases? If so, why use the while statement at all?

I will try to test this, but I'm new to Scala so it might take me some time. If someone would like to explain, that would be great.

Cheers!

Chris
  • 785
  • 10
  • 24
  • 5
    `while` loop in scala don't use pass-by-name parameter because there is no parameters in there at all as this is built-in language construct. But the behaviour is the same is it would be pass-by-name parameter. `whileLoop` just emulate the behaviour of native `while` using pass-by-name parameters. – Bogdan Vakulenko May 24 '19 at 10:01
  • 1
    "improving performance" is the least part of it. You use a `while` loop for side effects, not for the result of the expression. So you really need to get that loop body executed as many times as the expression wants it to, and with a different "context" every time. How else are you going to print first "2", then "1"? You cannot just do single `print` upfront because of performance considerations. It would produce completely different effects. – Thilo May 24 '19 at 10:31
  • @Thilo Thanks for commenting. I wasn't sure if that would be the case because the way the documentation worded that the method implementation of `whileLoop` can ignore the body for umatched conditions, I assumed that they were also inferring that the `while` statement's body will be evaluated whether or not the condition was met (although that's probably not possible). At least this was my reasoning for the question. – Chris May 24 '19 at 10:35

2 Answers2

5

The while statement is not a method, so the terminology by-name parameter is not really relevant... Having said so the while statement has the following structure:

while(condition){
  body
}

where the condition is repeatedly evaluated and the body is evaluated only upon the condition being verified, as show this small examples:

scala> while(false){ throw new Exception("Boom") }
// Does nothing

scala> while(true){ throw new Exception("Boom") }
// java.lang.Exception: Boom

scala> while(throw new Exception("boom")){ println("hello") }
// java.lang.Exception: Boom
Valy Dia
  • 2,781
  • 2
  • 12
  • 32
  • Ah yeah sorry it doesn't make sense for it to be a method. It's just a token that precedes following statements to be evaluated a certain way, if that's right? I'm going to update my question – Chris May 24 '19 at 10:25
4

Would a method implementation of the while statement perform better than the statement itself if it's possible not to evaluate the body at all for certain cases?

No. The built-in while also does not evaluate the body at all unless it has to, and it is going to compile to much more efficient code (because it does not need to introduce the "thunks"/closures/lambdas/anonymous functions that are used to implement "pass-by-name" under the hood).

The example in the book was just showing how you could implement it with functions if there was no built-in while statement.

I assumed that they were also inferring that the while statement's body will be evaluated whether or not the condition was met

No, that would make the built-in while totally useless. That is not what they were driving at. They wanted to say that you can do this kind of thing with "call-by-name" (as opposed to "call-by-value", not as opposed to what the while loop does -- because the latter also works like that).

The main takeaway is that you can build something that looks like a control structure in Scala, because you have syntactic sugar like "call-by-name" and "last argument group taking a function can be called with a block".

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • Thanks for your help, your answer makes a lot of sense.. I certainly misunderstood the explanation in the documentation, thank you for clarifying. I think I need to brush up on my language processing knowledge. Do you know of any specific sources where I could read up on language processing for Scala? No problem if you don't, I'll try find some either way. – Chris May 24 '19 at 10:47