Proposal: Partial access to variables in a `with` statement from the `else` block

54 views
Skip to first unread message

ma...@lamarciana.com

unread,
Jul 5, 2017, 8:16:22 AM7/5/17
to elixir-lang-core
Hi!

Writing a phoenix application I came across a pattern which I think it could be quite common. For example, in a controller:

```
with {:ok, post} <- Blog.get_post(id),
        {:ok, :authorized} <- Blog.authorize_post(post),
        {:ok, updated_post} <- Blog.update_post(post, params)
do
  conn
  |> put_flash("Success!")
  |> render("show.html", conn: conn, post: updated_post)
else
  {:error, changeset_with_errors} ->
    {:ok, post} <- Blog.get_post(id)
     conn
     |> put_flash("Error!")
     |> render("edit.hml", conn: conn, post: post, changeset: changeset_with_errors)
```

In the case that the `with` statement matches the first and second match but not the third one, then the `else` clause for `{:error, changeset_with_errors}` is executed. There, even if `post` variable had already been matched in the `with` statement, I need to "match it again" in order to use it.

I know I could match it before entering the `with` statement and just authorize and update in it, but it is a pity that then the happy path is less clear to read.

So, what I'm thinking is that maybe it would be nice to have access, if possible, in `else` clauses to the variables that has been matched in the `with` part.

What do you think?

Thank you

José Valim

unread,
Jul 5, 2017, 8:40:33 AM7/5/17
to elixir-l...@googlegroups.com
Then you want to use a case. Your variant is inherently unsafe, as there is no guarantee the "post" variable has been set or not. Elixir was used to initialize variables to nil but this behaviour has been deprecated since 1.2 or 1.3 as it was very confusing.



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/01aca5e8-1ae0-412e-9b96-49c2ed87342e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ma...@lamarciana.com

unread,
Jul 5, 2017, 10:32:44 AM7/5/17
to elixir-lang-core, jose....@plataformatec.com.br
Ok, now I understand. When you replied I first thought that it would be possible if Elixir were a statically typed language, because the compiler could know that {:error, a_changeset_struct} was an output from the third match, therefore allowing variables from previous matches. But anyway this behavior would be broken when two matches returned the same type.

Thanks for your response!
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

José Valim

unread,
Jul 5, 2017, 11:04:04 AM7/5/17
to ma...@lamarciana.com, elixir-lang-core
To be fair I think the behaviour would be invalid even on statically typed languages, as there would be no type for the variable at all (unless they assign nil/null to it).



José Valim
Skype: jv.ptec
Founder and Director of R&D

Reply all
Reply to author
Forward
0 new messages