Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

if else one-liner #2994

Closed
reversepanda opened this Issue · 9 comments

5 participants

@reversepanda

Sorry, if this has been asked before: using a if-else one liner gave me an unexpected behavior so I wondered if this is expected:

Example

  class X
      func: ->
          a = "f"
          @[a]() if a of @

will translate to

var X;
X = (function() {
  function X() {}
  X.prototype.func = function() {
    var a;
    a = "f";
    if (a in this) {
      return this[a]();
    }
  };
  return X;
})();

while

class X
    func: ->
        a = "f"
        @[a]() if a of @ else alert "do something else"

will give

var X;
X = (function() {
  function X() {}
  X.prototype.func = function() {
    var a;
    a = "f";
    return this[a]()(a in this ? void 0 : alert("do something else"));
  };
  return X;
})();

Difference: in the second example @[a]() is called in any case (and thus might throw an exception if @a does not exist, when the intention was that the if would secure that). I understand why this happens due to how the if-else one liner is translated to the JavaScript ?: operator, but wouldn't it be more intuitive to translate a missing then clause in a if-then one liner to

    return (a in this ? this[a]() : alert("do something else"));

Or is it invalid code to leave out the then clause in such a case? Because currently the compiler does not report this as a syntax error.

@michaelficarra
Collaborator

Yes, it looks like the compiler is allowing you to omit the then when it shouldn't be. Marking as bug.

@epidemian

The crux of the problem seems to be that...

if a else b

... is valid syntax. I agree with @michaelficarra in that the then should be compulsory in that case. I'd also like it if the compiler would raise a warning about the empty if block or something, as it's most certainly an error (though i'd also respect the opinion of leaving all linting stuff outside the compiler itself).

@reversepanda

I am coding too much in Python where if else one-liners without then is valid (see http://en.wikipedia.org/wiki/Conditional_operator#Python). :) But then this is not Python. Though I personally would prefer having the option to leave out the then block (and translate to a version as described above), this might be an backwards incompatible language change or just too much work to support for such a small (subjective) benefit.

@epidemian

Yeah, i feel that supporting Python-style if expressions would not be good for CS. I'd even call it a misfeature of Python to have that weird syntactic distinction between if statements and if expressions, especially for a language that is supposed to have intuitive and simple syntax rules.

In CoffeeScript, every if is an expression, so you can rewrite your code as:

func: ->
  a = 'f'
  if a of @ then @[a]() else alert "do something else"
@vendethiel
Collaborator

clearly -1 for python's syntax

@reversepanda

Thanks @epidemian.

I believe my confusion came from the difference how my construct was translated to JS and what I had expected.

while exprA if exprB is just a shortcut for if (exprB) { exprA; }

exprA if exprB then exprC else exprD becomes a call(!): exprA(exprB ? exprC : exprD);.

Confusing at first, understandable at second glance. Still getting used to the fact that function calls do not need parenthesis.

So I believe my original problem was not due to the fact that the then-clause can be omitted (which might be a different issue altogether), but that this construct translates to something totally different than I expected. I had a function call when I was trying to be "one-liner-smart". :)

@vendethiel
Collaborator

@michaelficarra actually I think we allow if a else b for the same reason we allow for a : because some people might comment the inner code (considering it adds the block, that's probably a designed behavior). We should probably disallow it inline. pinging @jashkenas

@jashkenas
Owner

Right -- I think I recall allowing this ... but I'm at a loss as to why exactly. This needs to be writable:

value = if a then b else c

... but I can't think of a reason why you should be allowed to omit the matching half of the conditional. I'd leave it tagged as a bug that should be fixed.

Note that the original confusion still exists:

thing if a

... is a postfix if, whereas:

thing if a then b

... is a function call passing the conditional expression. I think that as long as we have postfix if, that's going to be a necessary evil.

@jashkenas
Owner

Merged the compulsory then. Should give an error now.

@jashkenas jashkenas closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.