Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
determin1st opened this issue Oct 31, 2016 · 7 comments
Open

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

determin1st opened this issue Oct 31, 2016 · 7 comments

Comments

@determin1st
Copy link

determin1st commented Oct 31, 2016

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

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

@akubera
Copy link

akubera commented Nov 2, 2016

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'?

@determin1st
Copy link
Author

determin1st commented Nov 5, 2016

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.

@foxbunny
Copy link

foxbunny commented Nov 5, 2016

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).

@ozra
Copy link

ozra commented Mar 10, 2017

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.

@determin1st
Copy link
Author

determin1st commented Mar 11, 2017

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)

@ozra
Copy link

ozra commented Mar 11, 2017

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.

@pepkin88
Copy link
Contributor

pepkin88 commented Mar 20, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants