LiveScript
LiveScript copied to clipboard
x ? (y > 0 ? 1 : 2) : 3; // problem in LiveScript
x = if y > 0 __then if z > 0 ____then 1 ____else 2 __else 3
Hello, this, i think might be a problem.. Should work.
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'?
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.
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).
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.
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)
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.
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.