开发者

CoffeeScript, Why do I need the explicit return on a conditional

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜