ponylang / rfcs

RFCs for changes to Pony
https://ponylang.io/
60 stars 48 forks source link

implement cond from Elixir as clean alternative to if / elseif / else #188

Closed igotfr closed 3 years ago

igotfr commented 3 years ago

https://elixir-lang.org/getting-started/case-cond-and-if.html#cond

cond
  2 + 2 == 5 ->
    "This will not be true",
  2 * 2 == 3 ->
    "Nor this",
  1 + 1 == 2 ->
    "But this will",
  true ->
    "This is always true (equivalent to else)"
end
cond
| 2 + 2 == 5 => "This will not be true"
| 2 * 2 == 3 => "Nor this"
| 1 + 1 == 2 => "But this will"
| true => "This is always true (equivalent to else)​"
end

same in Pony

if 2​ + ​2​ == ​5​ then
  "​This will not be true​"
elseif 2​ * ​2​ == ​3​ then
  "​Nor this"
elseif 1​ + ​1​ == ​2​ then
  "​But this will"
else
  "This is always true (equivalent to else)​"
end

11 lines difference

match None
| if 2 + 2 == 5 => "This will not be true"
| if 2 * 2 == 3 => "Nor this"
| if 1 + 1 == 2 => "But this will"
| if true => "This is always true (equivalent to else)​"
end
SeanTAllen commented 3 years ago

I dont see any point to this change. It's a breaking change and extra code for no gain that is apparent to me.

igotfr commented 3 years ago

I dont see any point to this change. It's a breaking change and extra code for no gain that is apparent to me.

@SeanTAllen It's the same as chain operator, pipe operator and syntax sugar in general, It's absolutely unnecessary, but people always want clarity, intuitiveness and readability

Then I think that all these should be evaluated and considered the same way, as ergonomics

jemc commented 3 years ago

I agree in preferring the ergonomics of this approach because it doesn't treat the first case differently in syntax from the following ones.

However, the syntax presented above doesn't match well with the existing Pony syntax. Particularly, the -> in today's Pony is only used in viewpoint adaptation and we use => for match, which this is most similar to in semantics.

If we were to use a syntax similar to Pony's match, it would still likely achieve your goals and be less disruptive to existing Pony syntax:

cond
| 2 + 2 == 5 => "This will not be true"
| 2 * 2 == 3 => "Nor this"
| 1 + 1 == 2 => "But this will"
| true => "This is always true (equivalent to else)"
end

For reference, in the Mare compiler I have adopted a similar approach, where the syntax looks like this:

case (
| 2 + 2 == 5 | "This will not be true"
| 2 * 2 == 3 | "Nor this"
| 1 + 1 == 2 | "But this will"
| "This is always true (equivalent to else)"
)
redvers commented 3 years ago

This is valid and close to what you're looking for:

match None
| if ("c" == "a") => env.out.print("allo a")
| if ("c" == "b") => env.out.print("allo b")
| if ("c" == "c") => env.out.print("allo c")
end

All lines now look identical.

(I didn't use numbers in the example above because you have to specify the type of each number and that would have made the example less clear)

redvers commented 3 years ago

in other words, replace "cond" with "match None" and put an explicit if () statement and you end up with an identical construct.

jemc commented 3 years ago

I actually didn't know it was possible to use an if "guard" inside of a match statement without a preceding matching expression for it to "guard". Today I learned!

redvers commented 3 years ago

The interesting thing about Elixir is that Syntax "niceties"™ are trivial to add because language extensions can be done without touching the compiler at all. A normal module in fact can make those kinds of changes because of their AST-based macro system (see quote and unquote in the Elixir docs).

Consequently, syntax changes in other languages can be significantly more complex to implement so the "bar" needed to be reached to take on that challenge will be higher.

@cindRoberta - I hope the syntax example that I gave is close-enough to a cond statement for you. It's just two extra characters :-)

redvers commented 3 years ago

@cindRoberta - since you've seen my last post - are you good with me closing this issue?

igotfr commented 3 years ago

@cindRoberta - since you've seen my last post - are you good with me closing this issue?

with cond would be simpler and ideal. And the match returns a (String | None) and if returns String. You are very polite asking me