LiveScript icon indicating copy to clipboard operation
LiveScript copied to clipboard

x ? (y > 0 ? 1 : 2) : 3; // problem in LiveScript

Open determin1st opened this issue 7 years ago • 7 comments

x = if y > 0 __then if z > 0 ____then 1 ____else 2 __else 3

Hello, this, i think might be a problem.. Should work.

determin1st avatar Oct 31 '16 19:10 determin1st

To restate the problem:

This code fails to compile (with an Error: Parse error on line 4: Unexpected 'ELSE') when you think it should pass; is that correct?

x = if y > 0
  then if z > 0
    then 1
    else 2
  else 3

The bug is else 2 on line 4 is not being "bound" to the associated if+then statements. Compiling after removing that line returns x = y > 0 ? z > 0 ? 1 : 3 : void 8; so it appears the else 3 is associated with the second if, instead of the 3rd.


The 'correct' syntax is to put the entire inner block inside the cascade.

x = if y > 0
  then
    if z > 0
    then 1
    else 2
  else 3

Alternatively, you can group the inner ternary operator with parens to disambiguate the else statements

x = if y > 0
  then (if z > 0
    then 1
    else 2)
  else 3

and x = if y > 0 then (if z > 0 then 1 else 2) else 3.


I'm not sure, but I have a feeling that the problem comes from the ambiguity of the else in the line if a then if b then x else y. Can the compiler check for the presence of a second else (after y) that would be associated with 'if a'?

akubera avatar Nov 02 '16 14:11 akubera

Oh, I see. Used your second version of "workaround" with (). I think JS ternary operator style is good (simple), but LiveScript's version more complicated.

determin1st avatar Nov 05 '16 20:11 determin1st

I think JS ternary operator style is good (simple), but LiveScript's version more complicated.

I feel that having a multi-line if-then block is actually more straightforward from the reader's perspective. JS ternary seems too clever and terse. Of course, LS is the king of terse among the languages targeting JavaScript, but that's not necessarily a good thing either. :)

When I say 'clever' I mean code that looks like "Look ma, no hands!" where the same thing can be expressed using a more common syntax (e.g., if-then block).

foxbunny avatar Nov 05 '16 20:11 foxbunny

I've coded in languages that only has the ternary operator, no if-then, so who's to say what's common syntax ;-)

Anyway, I've never seen then placement like that (well, corresponding, in bash scripts)!

I would spontaneously have written it like so:

x = y > 0 && (z > 0 && 1 || 2) || 3

But as we all know, this is walking on thin ice in JS - but I still find it cleanest. And ofc. in LS: watch out for and/or (would not yield expected result above)

Alternatively, like so:

x = if y > 0 => (if z > 0 => 1 else 2) else 3

And if it must be multi-line, what I think should be the "right" way doesn't work in LS (I find this to be a huge flaw in the language actually!)

# Eaaak - LS can't handle this, boohoo
x = if y > 0
       if z > 0
          1
       else
          2
    else
       3

I see no reason for conflict in allowing the above in the language, so I think it's just a flaw/oversight in the compiler implementation. Anyone enlighten me?

So, in practise, if having to write it multiline, it would perhaps be:

x = if y > 0
   if z > 0
      1
   else
      2
else
   3

But that's not pretty.

ozra avatar Mar 10 '17 00:03 ozra

nice comment ozra,

your example: x = y > 0 && (z > 0 && 1 || 2) || 3

looks complicated) and will work with numbers better to my taste. the case, when you need some more cases) in comparison may look more complicated..

suppose, its all about thens aligned with elses.. ternary operator like that:

x = if y > 0 ? if z > 0 ? 1 : 2 : 3

i believe, would be hard work to implement in LS. only the one who know the lexer could possible do that)

determin1st avatar Mar 11 '17 10:03 determin1st

The ? operator has an important function in LS - it wouldn't be possible to solve grammatically! You'll simply have to manage without ternary in LS.

ozra avatar Mar 11 '17 13:03 ozra

That is the only thing I miss from JS syntax, the conciseness of the ternary operator.

If someone's interested, this is how I usually format those operations:

x = if y > 0
  if z > 0
    1
  else 2
else 3

but if I can, and if it fits better, I use the implicit switch (the example shows the equivalent code to the previous one):

x =
  | y <= 0 => 3
  | z <= 0 => 2
  | _      => 1

I hope someone will find it helpful.

pepkin88 avatar Mar 20 '18 23:03 pepkin88