Closed Apanatshka closed 9 years ago
To be clear, the final else
is still required, and this is basically avoiding writing else
on branches 1 (zero-indexed) to n-1? Then that sounds good to me.
Yes, and I just added the consideration to force rather than allow not writing else
on all but the last branch in an if
chain. To avoid optional syntax (which I'm against).
I am also against optional syntax in theory, but I don't see how you'd disallow the else
. It's a natural use of the 2-way form, and you can use other proposal's syntax in 0.15. You'd certainly need a good compiler error ("omit the else
on all but the last conditional" or similar).
So we go from if Bool then a else a
to [if Bool then a]+ else a
.
I think this is a situation where an awesome error message will be super easy to do. I'll add a motivating example to consideration 3.
To me, the basic tradeoff between this and https://github.com/elm-lang/elm-plans/issues/3 seems to boil down to these benefits and costs:
Benefits:
else if
with if
, which is more conciseif
condition lines up vertically with what would otherwise be else if
conditionsCosts:
if
and else
and then just use them together)if
and else if
are super common, including in JS itself.I honestly don't think saving an else
worth of characters matters for something that comes up this infrequently; I still have only had occasion to use two-way if
expressions in all the Elm code I've written to date.
Similarly I don't know that lining up is a terribly large benefit here...and of course, if it is, you can always add another five spaces after if
so that they line up despite the else
. That would look a bit weird, granted, but the proposed syntax also looks weird to me because I habitually think "Oh no! An if
without an else
! I must have messed up my indentation somewhere!"
Personally I value "be less alien" over the conciseness and the lining up here, so I'd prefer #3 to this.
most people haven't seen the
then
before when not familiar with FP
A bit off-topic, but FYI I've seen then
in Ruby, CoffeeScript, Bash Scripting, and good old BASIC, my first programming language. :smile_cat:
Cost 1: is it really that big a cost to learn that you can chain if
and leave off the else
?
Cost 2: Python has elif, so does the C preprocessor and F#, other languages have elseif, Haskell has a multi-way if extension. I don't think this is alien.
I don't think the indentation rules allow you to indent the if 5 spaces and not the else... Even if it did, that would look weird and would never be in the Elm style guide (I imagine).
I'm more susceptible to the argument that an if
without else
would look wrong, but that's an adjustment you have to make with any new syntax.
I think lining things up if a great benefit that is being dropped in the style guide often enough already for the benefit of nicer textual diffs.
A bit off-topic, but FYI I've seen then in Ruby, CoffeeScript, Bash Scripting, and good old BASIC, my first programming language. :smile_cat:
I guess I don't know my languages well enough then :astonished:
Cost 1 is not that big, but neither benefit is that big either (unless I'm missing something?)
The alienness is a bigger deal for me than either of those. elif
and elseif
and else if
are all different than repeating if
; what I meant is that I've never seen a language where you can have if
followed by another if
and have them be part of the same expression. As far as I know, it's an unprecedented syntax for a common language feature.
Actually a significantly larger problem just occurred to me...this looks like valid JS code - but code that does something completely different!
Consider this valid JS code:
if (condition1)
console.log("foo");
if (condition2)
console.log("bar");
else
console.log("baz");
In JS, if both condition1
and condition2
are truthy, you will get both "foo"
and "bar"
logged to the console. In this Elm proposal, only the top branch would be followed.
Given that, this seems like it has huge potential for confusion. :crying_cat_face:
Use when instead of if. when and else will line up. It's readable by everyone.
I think the JS code is pretty good evidence against this.
Ruby uses when pattern then result
but it's part of a case
statement, which in Elm is a separate construct. And I'd like to do this without adding too much more syntax.
CoffeeScript also uses when
in case
expressions...I think that one would be too confusing.
Ah, the JS example really kills the syntax in this proposal :disappointed:
How about no repeated if
?
if
string == "you" then -- if string == "you" then
"what?" -- "what?"
string == "should" then -- else if string == "should" then
"hmm" -- "hmm"
string == "have" then -- else if string == "have" then
if
seenRatRace then -- if seenRatRace then
"I know where this is going" -- "I know where this is going"
else -- else
"should have what?" -- "should have what?"
string == "bought" then -- else if string == "bought" then
"uh oh" -- "uh oh"
string == "a" then -- else if string == "a" then
"bag of nuts?" -- "bag of nuts?"
string == "squirrel" then -- else if string == "squirrel" then
"ooh.. oh nuts, we're gonna crash" -- "ooh.. oh nuts, we're gonna crash"
else -- else
"gah! a skeleton!" -- "gah! a skeleton!"
Looks like it would fit the Elm style, it's spaced vertically in a similar way to let
.
(I'm not giving up on this yet, I think without distracting extra syntax around this looks much better and easier to read. )
So that's basically taking the current syntax, eliminating the bars, and using else
instead of otherwise ->
. Hmm.
How about arrows like in the case
syntax?
if
string == "you" ->
"what?"
string == "should" ->
"hmm"
string == "have" ->
if
seenRatRace ->
"I know where this is going"
else ->
"should have what?"
string == "bought" ->
"uh oh"
string == "a" ->
"bag of nuts?"
string == "squirrel" ->
"ooh.. oh nuts, we're gonna crash"
else ->
"gah! a skeleton!"
(nvm, looks super ugly)
I think we're getting too far afield here. (But that's good, it means we're searching thoroughly.)
@mgold Yes, that's the idea. And distinguishing the then
branches and the else
branch with different indentation looks nice to me. It seems clearer when you have multiple branches, not strange when you have one (then
) branch, and makes it feel similar to the let
.
@TheSeamau5 Yeah, the arrow is not better than just using then
IMHO. It looks weird on the else
, and generally doesn't read as nicely. Since it's always on the end of a sentence and highlighted, the then
feels almost as lightweight as ->
. (And yes, the arrow looks ugly :P)
I'm closing this repo down. I have this on my personal list of things to do.
(I thought that would sound friendlier than "Remove" :smiley: )
Proposed change
Merge
if
-then
-else
(two-wayif
) and multi-wayif
, keeping the best of both.The dreadful:
Becomes the delightful:
Two-way
if
s would remain valid, but now you can easily add extra branches, basically without having to writeelse if
.(Other syntax options like
->
instead ofthen
or leaving off subsequentif
s can be discussed of course. But this seems the nicest option to me right now. )Motivation
Having two constructs like this means there are two ways to do things, which is bad (IMHO, I wish I had a link to some article that argues the same).
Pros of two-way
if
:then
before when not familiar with FP)else
branch has to be writtenPros of multi-way
if
:Cons of multi-way
if
:|
bar which is alien and frustrates style guidesNot indentation sensitive, which is a bug that leads to it being un-nestable
Considerations
But it's actually a nice feature, because the above can be written without the
Debug.crash
if you make one of those conditional branches theelse
branch, and in some cases it will point people at a place where a union type could be a better fit.if
s" situation, but that would mean you're forced to write this kind of stuff:Not dreadful, but could be better.
else
is optional syntax in anif
-else
-if
chain. That's what I'm always against! So I'd really like to enforce the use of this multi-wayif
when chainingif
s. I think that's reasonable. Here's an example where I think removing theelse
on all but the last makes things clearer:(http://youtu.be/zfmZSiFlgKU)