Thanks Joel for the proposal.

I am not a big fan of a macro changing what = means. = typically means
pattern matching and a MatchClause error in case they don't match. Sure, we
can change what it means, but if = starts meaning different things in
different places, developers would constantly start to second guess
themselves.

Even inside for and with-comprehensions, = means MatchClause error and they
introduce an explicit <- construct for "soft matching". So maybe we could
do:

<%= if %{bar: bar} <- foo do %>
  ...
<% end %>

But then you might as well use with:

<%= with %{bar: bar} <- foo do %>
  Do that
<% end %>

Although the best solution here would be to move the logic to helper
functions. I would prefer to avoid pattern matching in templates.


*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D


On Thu, Oct 17, 2019 at 9:04 PM Joel Wietelmann <[email protected]> wrote:

> Scenario: You have one pattern you want to match. You do not want to raise
> a NoMatchError when the value fails to match this pattern.
>
> Probably the best available thing to do is to use a `case` statement:
>
> case foo do
> %{bar: "baz"} -> "hello i match"
> _ -> nil
> end
>
> However, that default case can get pretty repetitive when it's frequently
> nothing, and it gets even more awkward inside of EEx:
>
> <%= case foo do %>
> <% %{bar: "baz"} -> %>
> hello i match
> <% _ -> %>
> <% end %>
>
> There's also `Kernel.match?/2`, which is awkward to use in an `if`
> statement because it doesn't read like any pattern matching expression that
> an Elixir developer has typically ever written:
>
> if match?(%{bar: "baz"}, foo) do
> "yes"
> end
>
> Here is an alternative idea, which I think is significantly easier to read
> than the above options:
>
> if_match %{bar: "baz"} = foo do
> "yes"
> else
> "no"
> end
>
> if_match %{bar: "not baz"} = foo do
> "yes"
> end
>
> <%= if_match %{bar: "baz"} = foo do %>
> hello i match
> <% end %>
>
> Proof of concept code:
>
> defmacro if_match(expression, do: do_clause) do
> quote do
> match(unquote(expression), do: unquote(do_clause), else: nil)
> end
> end
>
> defmacro if_match({:=, _, [pattern, value]}, do: do_clause, else:
> else_clause) do
> quote do
> case unquote(value) do
> unquote(pattern) ->
> unquote(do_clause)
>
> _ ->
> unquote(else_clause)
> end
> end
> end
>
> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/4944626e-7cde-4200-ae3a-e573102246a2%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/4944626e-7cde-4200-ae3a-e573102246a2%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BA2QP2brLDGcF6jTMx1bczSwOxv%3D4P5hhEN9zYVj6maQ%40mail.gmail.com.

Reply via email to