-3

Possible Duplicate:
Return in Scala

I have just started using Scala and have come across some behavior that I don't really understand, and I'm hoping the stackoverflow community can shed some light.

Using this test:

example(1,List(1))

This code works as I would expect - 0 is returned on the second iteration:

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    return 0
  else
    return 1
  example(value - list.head, list.tail) + example(value, list.tail);
}

However, this code does not - it throws a NoSuchElementException("head of empty list") on the second iteration:

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    0
  else
    1
  example(value - list.head, list.tail) + example(value, list.tail);
}

The difference appears to be that in the second example, Scala is assuming "0" and "1" are not return values but expressions to be evaluated because there is another expression at the end of the function. It makes sense that the first example would return as expected due to the explicit "return" keyword.

However, given the syntax of the if statement in second example, I would think the compiler would realize that "0" is not an expression to be evaluated, but rather a return value. Why is this not the case?

Bi Rico
  • 25,283
  • 3
  • 52
  • 75
spork
  • 1,185
  • 1
  • 11
  • 17
  • 2
    This exact question was asked earlier today: http://stackoverflow.com/questions/12560463/return-in-scala – dhg Sep 25 '12 at 01:05

1 Answers1

0

You should read the answer here for information about implicit returning since that part of your question is an exact duplicate.

But I'll answer specifically your point about "I would think the compiler would realize that "0" is not an expression to be evaluated, but rather a return value", since it's an interesting observation.

The simple answer is that 0 is an expression... it just happens to be the case that its evaluation is pretty simple. Scala doesn't make a distinction between "expressions that require effort" and "expressions that are easy" when it decides how to process your code. It just processes it the way it's told.

More importantly, if the Scala compiler did get into the business of guessing your intent, that would get pretty crazy, and would make coding a lot more challenging!

To see why we do not want this, let's look at your code that you posted:

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    0
  else
    1
  example(value - list.head, list.tail) + example(value, list.tail);
}

As you mentioned, the 0 and 1 bits aren't really doing anything. So maybe this hypothetical compiler would say "Hey! The only interesting thing I can do with these is to return them!" and thus makes them return. We'll now we've got an if/else in which both sides return. In other words, if list is empty, we return, and if it's not empty, we return. So we always return, and the function ends.

But wait!! There's another line after the if/else expression! So our hypothetical compiler says "Hey! If I return here, then I won't ever execute that line! And that line looks pretty important. Maybe I shouldn't return, so that I can execute it." But then it realizes "Oh no! If i don't return the 0 or 1, then they are pointless! I have to return them!". "But that last line is still there!". "Ahhhhhhh!!!!1!!".

So maybe it's better that the compiler doesn't try to guess what we want and instead just does what we tell it.

Community
  • 1
  • 1
dhg
  • 52,383
  • 8
  • 123
  • 144
  • 4
    When compiler or interpreter *tries to guess* really [bad things are happining](https://www.destroyallsoftware.com/talks/wat). – om-nom-nom Sep 25 '12 at 01:22
  • @om-nom-nom, I which I could give you rep for the link in your comment. :-) :-) – dhg Sep 25 '12 at 01:25