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

Syntax proposal if let #1301

Open
jaredly opened this issue Jun 14, 2017 · 7 comments
Open

Syntax proposal if let #1301

jaredly opened this issue Jun 14, 2017 · 7 comments
Labels
Parser parsing reason code into an AST RFC For larger proposals/ideas that will need discussion

Comments

@jaredly
Copy link
Contributor

jaredly commented Jun 14, 2017

In swift, there's this nice construct for simple destructuring

if case .someEnumVariant(let value) {
 ...
} else {
 ...
}

It's basically a one-armed match.
It would be super handy to have that for reason, and I imagine it would look like

if let [%pattern] = [%value] {
  // x
} else {
  // y
}

which we'd translate to

switch [%value] {
| [%pattern] => // x
| _ => // y
}
@pjhenning
Copy link
Contributor

pjhenning commented Jun 14, 2017

Yes its occasionally nice being able to do (a bit redundant here but this is the specific use case I had been thinking about):

if let aValue = anOptional {
    doSomethingWith(aValue)
}

@jaredly
Copy link
Contributor Author

jaredly commented Jun 15, 2017

Other discussion from the ocaml folks
ocaml/ocaml#194
https://caml.inria.fr/mantis/view.php?id=6685

I'm not very moved by their counterarguments. I think if let is much more accessible to folks coming from javascript etc., to whom Option.iter would be foreign.

@jaredly
Copy link
Contributor Author

jaredly commented Jun 15, 2017

Another thing that swift's if let does might be quite useful (found myself wanting it in code I'm writing just now)

if
  let Some(x) = optx,
  let Some(y) = opty,
  let Some(z) = optz
{
 // all your things are here
}

is much nicer imo than

switch (optx, opty, optx) {
| (Some x, Some y, Some z) => ...

(especially if optx is some non-trivial expression)

@ckknight
Copy link
Contributor

I think using and instead of , let as a connector for multiple guards could work well particularly because it's the same syntax used with let rec x = ... and y = ...;

e.g.

if let Some(x) = optx
   and Some(y) = opty
   and Some(z) = optz
{
 // all your things are here
}

@jaredly
Copy link
Contributor Author

jaredly commented Mar 22, 2018

It's a cool idea! One thing that might be confusing is that I want successive cases to be able to use values from previous cases.
e.g.

if let Some(x) = optx,
   let Awesome(y) = doSomethingWith(x) {
}

and syntax in ocaml requires them to not use each other, and let rec and requires them to be functions. So something like

let x = 2
and y = x

is invalid.

@ckknight
Copy link
Contributor

Fair, this pattern seems like a pretty great way to guard:

if let Some(x) = getValue(),
   let Some(y) = doSomething(x),
   let Some(z) = doSomethingElse(z) {
  doSomethingCool(z);
} else {
  failwith("Couldn't do the thing!");
}

The ability to use the inner values makes it superior to

switch (a, b, c) {
  | (Some(a), Some(b), Some(c)) => ...,
  _ => ...
}

It'd have to be expressed as a series of nested switches or ifs, which would be less clear and add unnecessary nesting.

@gilbert
Copy link

gilbert commented Apr 13, 2018

For reference, this is similar to Elixir's with statement:

opts = %{width: 10, height: 15}
with {:ok, width} <- Map.fetch(opts, :width),
     {:ok, height} <- Map.fetch(opts, :height),
     do: {:ok, width * height}
#=> {:ok, 150}

@jaredly jaredly added KIND: FEATURE REQUEST RFC For larger proposals/ideas that will need discussion Parser parsing reason code into an AST and removed KIND: FEATURE REQUEST labels Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Parser parsing reason code into an AST RFC For larger proposals/ideas that will need discussion
Projects
None yet
Development

No branches or pull requests

4 participants