<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="73276" data-post-id="73276">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mgwidmann" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mgwidmann/120/7249_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mgwidmann
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>If this were more widely used, couldn’t Elixir having all patterns defined be able to add in more compile time checks to catch pattern matching errors?</p>
<p>Also, I do see some use in the ability to use guards in plain patterns. The match <code>=</code> operator in particular it becomes useful in doing something like <code>%{data: data} when is_binary(data) = request_data()</code></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73276" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-73276" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73276"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="73277" data-post-id="73277">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mgwidmann" data-post="22" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mgwidmann/48/7249_2.png" class="avatar"> mgwidmann:</div>
<blockquote>
<p>If this were more widely used, couldn’t Elixir having all patterns defined be able to add in more compile time checks to catch pattern matching errors?</p>
</blockquote>
</aside>
<p>Yes, in fact that was part of my original defguard proposal, by baking it into elixir that a guard can handle matching, binding, and guard tests then that opens a lot of capabilities.</p>
<aside class="quote no-group" data-username="vic" data-post="20" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>Not normally, but just for you I’ve added an experimental workaround for that case. See the last commit foo_test.exs. also might be interesting for you ast_test.exs</p>
</blockquote>
</aside>
<p>I just got an idea, what about using <code>?</code> for match and <code>!</code> for creation as disambiguation (or just <code>!</code> and no-prefix for matchers)?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73277" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-73277" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73277"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="73314" data-post-id="73314">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="vic" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/120/11426_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  vic
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Asdf Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="21" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>adding a defguard thing too like in mine so someone can add a guard to a def that can add multiple guards and/or matchers like mine?</p>
</blockquote>
</aside>
<p>I think I don’t understand what you mean with multiple matchers, could you provide an example of what syntax you use in yours and what would you want it to expand into?</p>
<p>Let me ellaborate a bit on how expat expands maybe could be useful for other people following this thread:</p>
<p>When you define  <code>defpat foo(1)</code>, the ast inside foo (here <code>1</code>) is the code that will be placed at call-site. eg. <code>foo() = 1</code> expands to <code>1 = 1</code>.</p>
<p>That means it’s actually possible to place <em>any</em> elixir code in there, and the <code>foo</code> macro will just expand it when called.</p>
<p>Now, since <code>expat</code>’s purpose in life is to help with pattern matching,<br>
the ast inside foo is treated specially in the following cases:</p>
<ul>
<li>
<p>if it contains a variable like <code>defpat foo(x)</code> then x is <em>boundable</em> by the caller of foo. The caller can bind it by name, like:<br>
<code>foo(x: 1) = 1</code> =&gt; <code>1 = 1</code><br>
If x is not bound by the caller, like <code>foo()</code>, x will be replaced with an <code>_</code> , so <code>foo() = 1</code> is <code>_ = 1</code></p>
</li>
<li>
<p>if it contains a guard like <code>defpat bar(y) when y &gt; 10</code> then, the code of the guard will also be expanded, for example:<br>
<code>bar(y: 2)</code> will expand to <code>y  = 2 when y &gt; 10</code>.</p>
<p>Note however that since we have a guard to check, and <code>y</code> is being used in it, the variable <code>y</code> is preserved in expansion, however this <code>y</code> is higenic (elixir’s counter distingishes it from others) and will not bind any other y in your own scope.</p>
<p>To bind in your scope you do something like<br>
<code>bar(y: u)</code> expands to <code>u = y when y &gt; 10</code> and <code>u</code> is a variable you provided from your scope.</p>
<p>So, you could bind bar’s <code>y</code> with any expression, even other pattern expansions (just regular function calls)</p>
<p><code>bar(y: z = foo(x: 20))</code> will expand to <code>y = z = 20 when y &gt; 20</code><br>
this will also work: <code>bar(z = foo(20))</code>  since expat now supports positional arguments (variables get bound in the order they appear on the pattern)</p>
</li>
<li>
<p>If it contains a nested pattern expansion. For example, if you had<br>
<code>defpat t2({x, y}) when x &gt; y</code> and later did<br>
<code>defpat teens(t2(bar(a), bar(b))) when a &lt;  20 and b &lt; 20</code></p>
<p>Then <code>teens</code> has two <em>bindable</em> names, <code>:a</code> and <code>:b</code> and it will get expanded into a pattern like:<br>
<code>{a, b} when a &lt; 20 and b &lt; 20 and a &gt; b and a &gt; 10 and b &gt; 10</code><br>
That means inner guards get propagated into the calling expansion.</p>
</li>
</ul>
<p>Now since <code>defpat</code> just captures the code inside the pattern for expanding it later, <code>defpat named(%{"name" =&gt; name})</code> allows you to expand <code>named</code> anywhere you can place a pattern in elixir, like on the left hand side of <code>=</code></p>
<p><code>named(x) = %{"name" =&gt; "vic"}</code> will expand to<br>
<code>%{"name" =&gt; x} = %{"name" =&gt; "vic"}</code>, that’s why you can use it on a function definition like:</p>
<p><code>def index(conn, params = named(name)), do: ...</code></p>
<p>However, for those containing guards,</p>
<p><code>def lalala(teens(m, n))</code> would by itself expand into:<br>
<code>def lalala({m, n} when m &lt; 20 and n &lt; 20 and m &gt; n and m &gt; 10 and n &gt; 10)</code></p>
<p><em>Of course</em> having a <code>when</code> in that context fails.<br>
as it would do if you try:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(14)&gt; {m, n} when m &gt; n and m &gt; 10 and n &gt; 10 = {30, 20}
** (CompileError) iex:14: undefined function when/2
</code></pre>
<p>So, having guards was what introduced the <code>expat def</code> syntax:</p>
<p><code>expat def lalala(teens(m, n))</code> expands correctly into:<br>
<code>def lalala({m, n}) when m &lt; 20 and n &lt; 20 and m &gt; n and m &gt; 10 and n &gt; 10</code>.</p>
<p>Finally, that’s why <code>expat</code> is different from <code>defguard</code> both elixir’s and <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a>’s because for expat, expansion is  not limited to be used as part of a <code>when</code>. Named expat patterns can be used anywhere it’s valid to expand it’s containing expression.</p>
<p>So, hope that helps anyone.</p>
<p>If someone is interested, you can read more examples in the tests, and the docs, or use the source.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73314" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-73314" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73314"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="73318" data-post-id="73318">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="vic" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/120/11426_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  vic
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Asdf Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Oh btw, generated macros now get documented.</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/2X/3/3d4d5e18688de2916154573cbb37b7f626fed91e.png" data-download-href="https://forum.elixirforum.com/uploads/default/3d4d5e18688de2916154573cbb37b7f626fed91e" title="49%20PM" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/2X/3/3d4d5e18688de2916154573cbb37b7f626fed91e.png" alt="49%20PM" data-base62-sha1="8KiSRFCrlMYnhQNNqj5kxa5cckC" width="600" height="600"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">49%20PM</span><span class="informations">656×656 165 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73318" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-73318" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73318"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="73398" data-post-id="73398">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="vic" data-post="24" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>I think I don’t understand what you mean with multiple matchers, could you provide an example of what syntax you use in yours and what would you want it to expand into?</p>
</blockquote>
</aside>
<p>What my defguard did was you could define something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defguard is_exception(%{__struct__: struct_name, __exception__: true}) when is_atom(struct_name)
</code></pre>
<p>This could then by used like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def blorp(_exc) when is_exception(_exc), do: "exceptioned"
  def blorp(val), do: "No-exception:  #{inspect val}"
</code></pre>
<p>And it does expand as expected.  Specifically since <code>_exc</code> is passed into the <code>is_exception</code> ‘guard’ then the <code>_exc</code> in the argument list gets a matcher added to it, while it also added the guard in the <code>is_exception(_exc)</code> position.  You could even match ‘out’ something by passing in more arguments in some custom defguard, but essentially the above example turned into:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def blorp(_exc = %{__struct__: struct_name$1, __exception__: true}) when is_atom(struct_name$1), do: "exceptioned"
  def blorp(val), do: "No-exception:  #{inspect val}"
</code></pre>
<p>It basically just allows treating a guard as something that can both match and guard at the same time.  This is more powerful than just what expat does now because currently expat can only add a single matcher and N guards, where with my defguard pattern above it allows for N matchers and N guards, like in this convoluted example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  defguard can_vote?(%Human{birthdate: utc_bd}, now) when (utc_bd + 60*60*24*365*18) &gt;= now

...

def vote(human, now) when can_vote?(human, now), do: ...
def vote(_, _), do: ...
</code></pre>
<p>Or whatever, the thing is that you can pass in multiple things, and notice that you can pass ‘out’ as well:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defguard bloop({a, b}, b) when is_atom(a)

...

def blorp(c) when bloop(c, d), do: d
</code></pre>
<p>So here you can see that it passes ‘out’ something as well, and you just put a binding there.  Notice that you can put a specific value there too like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def blorp(c) when bloop(c, :ok), do: ...
</code></pre>
<p>So now that will only match <code>{a, :ok}</code> where <code>a</code> is an atom.  The thing is that instead of just being 1-matcher/N-guards, it is N-matchers/N-guards, <em>and</em> since it is in the guard position then you can use <a href="https://hexdocs.pm/elixir/Macro.Env.html#in_guard?/1" rel="noopener nofollow ugc"><code>in_guard?/1</code></a> as usual to do the right action if in a guard or make it an expression, which means you could use it in statement positions properly like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">a = {:ok, :blah}
b = 42
if foo(a, b, c) do ... else ... end ...
</code></pre>
<p>And notice that you can match on yet ‘more’ things as well.  I could easily imagine adding the capability of having it support static KWLists so you could do things like this too if you want:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def blorp(c) when bloop(c, out: d), do: d
# or
if foo(the_tuple: a, an_arg: b, out: c) do ... else ... end ...
</code></pre>
<p>Or whatever as well.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="vic" data-post="24" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>That means it’s actually possible to place any elixir code in there, and the foo macro will just expand it when called.</p>
</blockquote>
</aside>
<p>Yep, same with the defguard style too.</p>
<aside class="quote no-group" data-username="vic" data-post="24" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>Now, since expat’s purpose in life is to help with pattern matching,</p>
</blockquote>
</aside>
<p>Instead of just supporting single matchers, what about supporting multiple?</p>
<p>I’m not saying replace the existing functionality with this, but rather ‘add’ the defguard stuff to expat as well, then it would have both the ability for N-Matchers/N-Guards via a ‘guard’ and for easy-inline 1-Matcher/N-Guards via the matcher style too.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="vic" data-post="24" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>Finally, that’s why expat is different from defguard both elixir’s and <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a>’s because for expat, expansion is  not limited to be used as part of a when.</p>
</blockquote>
</aside>
<p>Expansion is not limited to being used as part of when, it can be used as an expression with defguard as well as it essentially just appears as any normal function call.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73398" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-73398" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73398"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="75195" data-post-id="75195">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="vic" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/120/11426_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  vic
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Asdf Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><code>v1.0.4</code> features <em>Union Patterns</em>. Patterns composed into a single one, this lets you emulate things like:</p>
<ul>
<li><a href="https://github.com/vic/expat/tree/master/test/expat_nat_test.exs" rel="noopener nofollow ugc">Natural numbers</a>.</li>
<li><a href="https://github.com/vic/expat/tree/master/test/expat_maybe_test.exs" rel="noopener nofollow ugc">Maybe</a>.</li>
<li><a href="https://github.com/vic/expat/tree/master/test/expat_either_test.exs" rel="noopener nofollow ugc">Either</a>.</li>
<li><a href="https://github.com/vic/expat/tree/master/test/expat_union_test.exs" rel="noopener nofollow ugc">Union on Struct</a>.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="75195" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-75195" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="75195"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="75227" data-post-id="75227">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="vic" data-post="27" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>Natural numbers.</p>
<p>Maybe.</p>
<p>Either.</p>
<p>Union on Struct.</p>
</blockquote>
</aside>
<p>Oh now those are really cool!  Full matching and so forth without enforcing a structure, even the Maybe is just natural in elixir (still not big on the <code>nil</code> word, but eh, Elixir’isms).  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>EDIT1:  In the <code>maybe</code> test, you have this test:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  test "just can be pattern matched" do
    assert just() = :jordan
  end
</code></pre>
<p>What about having this too:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  test "just can be pattern matched and extract" do
    assert just(j) = :jordan
    assert j == :jordan  
  end
</code></pre>
<p>That shows you can extract as well.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>EDIT2:  How would you implement a Result type that accepted an <code>:ok</code>, <code>{:ok, value}</code>, <code>:error</code>, and <code>{:error, reason}</code> as an example?  That would show a variety of usages of using native types and no wrapping and so forth, preferably using <code>ok/0</code>/<code>error/0</code>/<code>ok/1</code>/<code>error/1</code> and such constructors.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="75227" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-75227" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="75227"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="75285" data-post-id="75285">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="vic" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/120/11426_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  vic
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Asdf Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yep, added your additional <code>Maybe</code> example, thanks. Also added a<br>
<a href="https://github.com/vic/expat/blob/master/test/expat_result_test.exs" rel="noopener nofollow ugc">Result</a> one.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="75285" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-75285" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="75285"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #28"></div>
  </section>
</div>
    <div class="postbit" id="75288" data-post-id="75288">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="vic" data-post="29" data-topic="3238">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vic/48/11426_2.png" class="avatar"> vic:</div>
<blockquote>
<p>Also added a</p>
<p>Result one.</p>
</blockquote>
</aside>
<p>I saw!  I also left a comment/question on that commit.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="75288" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-75288" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="75288"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #29"></div>
  </section>
</div>
    <div class="postbit" id="97474" data-post-id="97474">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi <a class="mention" href="/u/vic" rel="nofollow">@vic</a>,</p>
<p>I really enjoy the continuous work you have been doing in expat!</p>
<p>I wonder if we should support <code>when</code> clauses inside patterns and automatically move them out. So if you do:</p>
<pre><code>def foo(x when is_integer(x)), do: x
</code></pre>
<p>It becomes:</p>
<pre><code>def foo(x) when is_integer(x), do: x
</code></pre>
<p>while nobody would write the first in practice, it is very powerful for extending the language. It means you would be able to drop the <code>expat</code> prefix in many cases.</p>
<p>Similarly, regarding the union types, I wonder if instead of the expat prefix, you could use the prefix of the union, so <a href="https://github.com/vic/expat/blob/master/test/expat_maybe_test.exs#L38" rel="nofollow">this example</a> becomes:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  test "nil cannot be pattern matched with just" do
    maybe case Keyword.get([], :foo) do
      just() -&gt; raise "Should not happen"
      nothing() -&gt; assert :ok
    end
  end
</code></pre>
<p>Or even:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  test "nil cannot be pattern matched with just" do
    maybe Keyword.get([], :foo) do
      just() -&gt; raise "Should not happen"
      nothing() -&gt; assert :ok
    end
  end
</code></pre>
<p>Although I am not sure how that would play with nesting. For example, if you have a <code>maybe</code> with a <code>nat</code> inside, how would you handle it? Do you need two separate cases? I guess that would be the case, as a <code>nat</code> with a nothing doesn’t make sense. I wonder if other languages (OCaml/Haskell/F#) allow case to be “folded” in such cases or do they require an explicit case per pattern? /cc <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a></p>
<p>Thoughts?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="97474" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/expat-composable-reusable-pattern-matching/3238/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-97474" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="97474"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/3238/load_more?page=4">Load more posts (2 remaining)</a>
</div></template></turbo-stream>