[erlang-questions] Guards syntax for multiple values
José Valim
jose.valim@REDACTED
Wed Mar 27 02:17:01 CET 2019
> Everybody seems to be chasing after how to express "X in [...]" as a guard
without responding to the suggestion of copying SML/NJ's "or patterns"
What are the restrictions for OR patterns?
Can OR patterns be allowed anywhere in a pattern (i.e. arbitrarily nested)
or are they allowed only at the root?
Can we bind variables inside OR patterns?
I assume both are possible as long as after all combinations are expanded,
they all bind the same variable names?
> I am also puzzled that nobody seems to be concerned that the one and only
example we have of a use case is code that should never be written in the
first place
Since we do have this feature in Elixir, I can provide examples of where we
use it in the language, translated to Erlang.
I will use the is_member/2 syntax but anyone is welcome to translate it to
"X in Y" or the equivalent "OR patterns".
*Example 1: validate supervision restart*
validate_restart(_Name, Strategy)
when is_member([permanent, temporary, transient], Strategy) ->
ok;
validate_restart(Name, Strategy) ->
error({bad_strategy, Name, Strategy}).
Without is_member, you either need multiple clauses (which is ok in this
case, since the positive clauses only return ok) or write long guards (too
repetitive IMO).
*Example 2: rewriting Erlang binary operators into Elixir AST*
rewrite_guard_call(Op)
when is_member(['band', 'bor', 'bnot', 'bsl', 'bsr', 'bxor'], Op) ->
{'.', meta(), [bitwise, Op]};
rewrite_guard_call(Op) ->
...N other clauses...
I find this a very good example of is_member/2. Of course, the
functionality could be written differently, but I can't think of any
alternative existing *today* that would be as concise or as elegant as
is_member/2.
*Example 3: Checking if a character is unreserved according to URI (RFC
3986)*
Similar to the Unicode example except we are pinned against a RFC, so it
can't change:
char_unreserved(Char)
when Char >= ?0, Char =< ?9;
Char >= ?A, Char =< ?Z;
Char >= ?a, Char =< ?z;
is_member("~_-.", Char) ->
true;
char_unreserved(Char) when Char >= 0, Char <= 16x10FFFF ->
false.
And similar for reserved characters:
char_reserved(Char)
when is_member(":/?#[]@!$&\'()*+,;=", Char) ->
true;
char_reserved(Char) when Char >= 0, Char <= 16x10FFFF ->
false.
There are likely other examples but this should be enough to push the
discussion forward.
*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190327/2356af2c/attachment.htm>
More information about the erlang-questions
mailing list