<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">> <span style="font-family:monospace,monospace">Everybody seems to be chasing after how to express "X in [...]" as a guard</span></div><div class="gmail_default" style="font-family:monospace,monospace">without responding to the suggestion of copying SML/NJ's "or patterns"</div><div dir="ltr"><br></div><div>What are the restrictions for OR patterns?</div><div>Can OR patterns be allowed anywhere in a pattern (i.e. arbitrarily nested) or are they allowed only at the root?</div><div>Can we bind variables inside OR patterns?</div><div><br></div><div>I assume both are possible as long as after all combinations are expanded, they all bind the same variable names?</div><div dir="ltr"><br></div><div dir="ltr">> <span style="font-family:monospace,monospace">I am also puzzled that nobody seems to be concerned that the one and only</span><div class="gmail_default" style="font-family:monospace,monospace">example we have of a use case is code that should never be written in the</div><div class="gmail_default" style="font-family:monospace,monospace">first place</div><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div><br></div><div>Since we do have this feature in Elixir, I can provide examples of where we use it in the language, translated to Erlang.</div><div>I will use the is_member/2 syntax but anyone is welcome to translate it to "X in Y" or the equivalent "OR patterns".</div><div><br></div><div><b>Example 1: validate supervision restart</b></div><div><br></div></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div class="gmail_signature"><div><div><div><font face="monospace, monospace">validate_restart(_Name, Strategy)</font></div></div></div></div></div><div><div class="gmail_signature"><div><div><font face="monospace, monospace">    when is_member([permanent, temporary, transient], Strategy) -></font></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_signature"><div><font face="monospace, monospace">  ok;</font></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_signature"><div><font face="monospace, monospace">validate_restart(Name, Strategy) -></font></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_signature"><div><font face="monospace, monospace">  error({bad_strategy, Name, Strategy}).</font></div></div></blockquote><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div><div>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).</div><div><br></div><div><b>Example 2: rewriting Erlang binary operators into Elixir AST</b></div><div><br></div></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div><font face="monospace, monospace">rewrite_guard_call(Op)</font></div><div><font face="monospace, monospace">    when is_member(['band', 'bor', 'bnot', 'bsl', 'bsr', 'bxor'], Op) -></font></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">  {'.', meta(), [bitwise, Op]};</font></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">rewrite_guard_call(Op) -></font></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">  ...N other clauses...</font></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div></div></div></div></div></blockquote><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>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.</div><div><br></div><div><b>Example 3: Checking if a character is unreserved according to URI (RFC 3986)</b><br></div><div><b><br></b></div><div>Similar to the Unicode example except we are pinned against a RFC, so it can't change:</div><div><br></div></div></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">char_unreserved(Char)</font></div><div><font face="monospace, monospace">    when Char >= ?0, Char =< ?9;</font></div><div><font face="monospace, monospace">         Char >= ?A, Char =< ?Z;<br></font></div><div><font face="monospace, monospace">         Char >= ?a, Char =< ?z;<br></font></div></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">         is_member("~_-.", Char) -></font></div><div><font face="monospace, monospace">  true;</font></div></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">char_unreserved(Char) when Char >= 0, Char <= 16x10FFFF -></font></div></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">  false.</font></div></div></div></div></div></div></div></blockquote><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div><div>And similar for reserved characters:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">char_reserved(Char)</font></div><div><font face="monospace, monospace">    when is_member(":/?#[]@!$&\'()*+,;=", Char) -></font></div></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">  true;</font></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">char_reserved(Char) when Char >= 0, Char <= 16x10FFFF -></font></div></div></div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><font face="monospace, monospace">  false.</font></div></div></div></div></div></div></div></blockquote></div><div><br></div><div>There are likely other examples but this should be enough to push the discussion forward.</div><div><br></div><div><span style="font-size:13px"><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><b>José Valim</b></span></div><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><div><span style="font-family:verdana,sans-serif;font-size:x-small"><a href="http://www.plataformatec.com.br/" style="color:rgb(42,93,176)" target="_blank">www.plataformatec.com.br</a></span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Skype: jv.ptec</span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Founder and Director of R&D<br></span></div></span></div></span></div></div></div></div></div></div></div></div><div class="gmail_quote"><div> </div></div></div></div>