I was trying to learn CoffeeScript, and made this simple class as first try:
class test
fib: (x) ->
x if x == 0 || x == 1
(this.fib x-1) + (this.fib x-2)
t = new test
alert(t.fib(6));
This code doesn't work because it gets compiled without a return statement in the if statement. This works:
fib: (x) ->
return x if x == 0 || x == 1
(this.fib x-1) + (this.fib x-2)
Why do I need the explicit return ? Based on the language description, especially http://jashkenas.github.com/coffee-script/#expressions, I expected the x expression to be converted to a return by the compiler.
Why would you expect the x expression to be converted to a return? Only the last expression in a method or function is converted to a return.
In Jeremy's if/then/else example, there are two possible last expressions, and the coffeescript parser understands to be the case in an if/then/else, which is not what you have here: instead, you have on expression with no lvalue, followed by another perfectly valid expression. (There's some discussion as to whether or not the if statement itself is an expression; arguably, it should be read as one, but the compiled output of an if/then/else contains a return keyword in both the then clause and the else clause.)
The compiler can't read your mind. It doesn't know what your intent is there with that rvalue x expression. All it knows is that another perfectly valid expression in the same scope follows it.
To get the effect you want:
if x == 0 or x == 1
x
else
(@fib x-1) + (@fib x-2)
Or one-liner:
if x == 0 or x == 1 then x else (@fib x-1) + (@fib x-2)
It's because CoffeeScript doesn't know, for sure, that the x if x == 0 || x == 1 line is a return statement.
What you want is
class test
fib: (x) ->
if x == 0 || x == 1
x
else
@fib(x-1) + @fib(x-2)
Which compiles into
(function() {
var test;
test = (function() {
function test() {}
test.prototype.fib = function(x) {
if (x === 0 || x === 1) {
return x;
} else {
return this.fib(x - 1) + this.fib(x - 2);
}
};
return test;
})();
}).call(this);
Without the else, the conditional isn't the last block of the function, so doesn't get the return treatment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With