<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="20940" data-post-id="20940">
  <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="ibgib" data-post="11" 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/ibgib/48/2176_2.png" class="avatar"> ibgib:</div>
<blockquote>
<p>In the OO world (where I came from), I would use granular interfaces and gradually build more complex data structures with them.</p>
</blockquote>
</aside>
<p>Just updated the README to avoid possible confusion and added a note on how expat patterns could be used to <em>construct</em> data if you provide all bindings, I mean you’ve always had, but with expat you <em>abstract</em> the actual form and give it a name, <a href="https://github.com/vic/expat/blob/master/test/expat_test.exs#L53" rel="noopener nofollow ugc">like this example</a></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defpat ok {:ok, value}

ok(22) # =&gt; {:ok, 22}
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="20940" 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/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-20940" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="20940"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="20988" data-post-id="20988">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yeah, this is definitely my favorite new library. The primary gain from it for me is making things DRYer. Where before I would have map structures repeated in multiple function clauses, e.g.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def handle_cmd(%{"dest_ib" =&gt; dest_ib,
                 "context_ib_gib" =&gt; context_ib_gib,
                 "src_ib_gib" =&gt; src_ib_gib} = data, ..) when guard1 do
def handle_cmd(%{"dest_ib" =&gt; dest_ib,
                 "context_ib_gib" =&gt; context_ib_gib,
                 "src_ib_gib" =&gt; src_ib_gib} = data, ..) when guard2 do
</code></pre>
<p>which has redundancy in the <code>"var_name" =&gt; var_name</code>, as well in the function clause level. And <code>dest_ib</code> and <code>src_ib_gib</code> are used across multiple commands in many places. I’m now able to create a single file for the reused patterns:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule WebGib.Patterns do
  @moduledoc """
  Reusable patterns using expat
  """
  
  import Expat
  
  defpat dest_ib_        %{"dest_ib" =&gt; dest_ib}
  defpat src_ib_gib_     %{"src_ib_gib" =&gt; src_ib_gib}
  defpat context_ib_gib_ %{"context_ib_gib" =&gt; context_ib_gib}
  # ..
end
</code></pre>
<p><em>(NB: I am tacitly going with a <code>_</code> suffix to indicate a pattern vs the var name, but I’m not sure what other non-word characters are legal in elixir. I would rather prefix the pattern with a single character and would love any suggestions.)</em></p>
<p>And then I compose them above the function and consume them:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defpat fork_data_(
  dest_ib_() =
  context_ib_gib_() =
  src_ib_gib_()
)

def handle_cmd(fork_data_(...) = data, ..) when guard1 do
def handle_cmd(fork_data_(...) = data, ..) when guard1 do
</code></pre>
<p>EDIT: The <code>...</code> inside the pattern is literal syntax, which helps <strong>enormously</strong> with DRY. The other <code>..</code> just means other args.</p>
<p>This is ridiculously more DRY and readable. Definitely a powerful lib you made here! <img src="https://forum.elixirforum.com/images/emoji/apple/smile.png?v=15" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20"></p>
<p>Thank you! <img src="https://forum.elixirforum.com/images/emoji/apple/thumbsup.png?v=15" title=":thumbsup:" class="emoji" alt=":thumbsup:" 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="20988" data-batch-url="/posts/batch_likers">
                        4
                      </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/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-20988" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="20988"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="21321" data-post-id="21321">
  <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>This is a really nice project. Since you are exploring things on the area, here are some challenges/questions you can consider:</p>
<ol>
<li>
<p>Is it possible to extend expat to be a generalization of records? defpat contains an exact subset of the records functionality, which is the pattern matching one. It is also easy to see how <code>defpat</code> could be used for updates, all you need to do is to match on the value and then build another new value of exactly the same shape with the same variables in place except the ones you are replacing, etc.</p>
</li>
<li>
<p>Have you considered using another operator instead of <code>=</code> for mixing patterns? I believe your mixing of patterns is actually an intersection. If you assume that <code>%{"id" =&gt; id}</code> will match all maps with the <code>"id"</code> field, including <code>%{"id" =&gt; "foo", "name" =&gt; "baz"}</code>, and the pattern <code>%{"name" =&gt; name}</code> all maps with a <code>"name"</code> field, including the map mentioned above, when you specify <code>id() = name()</code> you are actually saying it should have BOTH patterns, <code>id()</code> AND <code>name()</code>. If you think of patterns as sets representing the structures they can match on, it is an intersection. Another reason to choose another operator is that the precedence will work in a way it won’t require parentheses, for example: <code>defpat subject id() &amp;&amp;&amp; name()</code>. <a href="https://github.com/elixir-lang/elixir/blob/master/lib/elixir/src/elixir_parser.yrl#L62-L66" rel="nofollow">Here is a list of operators</a>.</p>
</li>
</ol>
<p>There is one feature we could add to Elixir that would allow the library to become more powerful which is to allow guards inside patterns:</p>
<pre><code>def is_foo_or_bar(atom when atom in [:foo, :bar])
</code></pre>
<p>Of course nobody would write such in practice but supporting it would allow you to express patterns with guards:</p>
<pre><code>def is_foo_or_bar(foo_or_bar())
</code></pre>
<p>Which the Elixir compiler would then rewrite internally as:</p>
<pre><code>def is_foo_or_bar(atom) when atom in [:foo, :bar]
</code></pre>
<p>Anyway, this is very exciting and it is close to topics I am currently researching. <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"> I could expand more on both points above if you are interested. For example, if you are able to generalize defpat to records, you should also be able to generalize it for map updates, and if you define a pattern such as:</p>
<pre><code>defpat foo_bar_baz %{"foo" =&gt; {bar, baz}}
</code></pre>
<p>And then allow someone to update the nested tuple like this:</p>
<pre><code>map = %{"foo" =&gt; {1, 2}, "hello" =&gt; "world"}
foo_bar_baz(map, bar: 3)
#=&gt; %{"foo" =&gt; {3, 2}, "hello" =&gt; "world"}
</code></pre>
<p>Optimizations could allow you to compile <code>foo_bar_baz</code> to <code>%{map | "foo" =&gt; Map.fetch!(map, "foo") |&gt; put_elem(0, 3)}</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="21321" data-batch-url="/posts/batch_likers">
                        10
                      </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/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-21321" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="21321"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="21337" data-post-id="21337">
  <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>Hey José, thanks for your input!</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="14" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>expat to be a generalization of records?</p>
</blockquote>
</aside>
<p>haven’t explored this, but will try and report back how it goes.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="14" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>another operator instead of = for mixing patterns?</p>
</blockquote>
</aside>
<p>Actually, I’m doing nothing with operators in expat. It’s just that if you define a pattern like</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defpat foo %{"a" =&gt; a}
defpat bar %{"b" =&gt; b}
defpat baz(foo() = bar())

baz(...) = %{a: "missing b", c: "unused"} # this would expand to
%{"a" =&gt; a} = %{"b" =&gt; b} = %{a: "missing b", c: "unused"} 
</code></pre>
<p>so you are just using the standard <code>=</code> operator to match on two patterns at the same time. I just mentioned it on the README so people could know how to intersect two patterns (will <code>s/mixing/intersect/</code> that part on the guide)</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="14" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>allow guards inside patterns</p>
</blockquote>
</aside>
<p>That would be a nice idea to explore, not sure if guards should be inside of patterns in Elixir tho, and not sure if we <em>do</em> need to extend Elixir for it. Actually when I was writing Expat I got tempted to allow guards but didnt for the sake of simplicity and time (just being lazy actually, got things to do at Spec). But I was thinking of things like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defpat foo(%{"foo" =&gt; x, "bar" =&gt; y}) when x in [:foo, :bar] and is_binary(y)

# but the way Expat currenly works, doing
foo(y: 1) # would expand to
%{"foo" =&gt; _, "bar" =&gt; 1) when _ in [:foo, :bar] and is_binary(1)
# so when ignoring `x` like in the previous example, I'd need to also
# ignore any guard that uses it
# so just to KISS I went for not yet implementing guards
# (wanted to release early an gather feedback)
</code></pre>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="14" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>if you are able to generalize defpat to records, you should also be able to generalize it for map updates</p>
</blockquote>
</aside>
<p><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"> would be really nice, will see how far I can get and report back to you.</p>
<p>Thanks for reading!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="21337" 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/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-21337" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="21337"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="21342" data-post-id="21342">
  <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">
								<aside class="quote no-group" data-username="vic" data-post="15" 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>Actually, I’m doing nothing with operators in expat. It’s just that if you define a pattern like</p>
</blockquote>
</aside>
<p>Oh, I see! This is really clever.</p>
<aside class="quote no-group" data-username="vic" data-post="15" 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 would be a nice idea to explore, not sure if guards should be inside of patterns in Elixir tho, and not sure if we do need to extend Elixir for it.</p>
</blockquote>
</aside>
<p>My initial impression is that it is only possible with Elixir extensions since <code>(x when ...) = ...</code> is simply not supported today and if you expand a pattern with a guard inside a function signature, Elixir will fail to compile the code. But if you have found workarounds, please let me know!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="21342" 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/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-21342" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="21342"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="21381" data-post-id="21381">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="14" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Have you considered using another operator instead of = for mixing patterns?</p>
</blockquote>
</aside>
<p>I thought this also. It was a bit confusing but I just black-boxed it as “this is how you do it”.</p>
<p>I will say, however, that my understanding of Erlang/Elixir patterns was much improved just from looking at this lib. I had thought of patterns as the entire function signature, and I didn’t realize that Erlang docs give each argument match as individual patterns…So I gotta say thanks just for that. Huge improvement on my misconception.</p>
<p>PS I have started to convert my command functions (command pattern) to use this lib. It’s great. <img src="https://forum.elixirforum.com/images/emoji/apple/smile.png?v=15" title=":smile:" class="emoji" alt=":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="21381" 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/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-21381" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="21381"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="73083" data-post-id="73083">
  <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 group-livebook_core_team" data-username="josevalim" data-post="16" 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/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>But if you have found workarounds, please let me know!</p>
</blockquote>
</aside>
<p>Hey, good news, I’ve just <a href="https://github.com/vic/expat" rel="noopener nofollow ugc">released v1.0</a>, I did a major rewrite as I <em>really</em> wanted (and needed) it to <a href="https://github.com/vic/expat#guarding-patterns" rel="noopener nofollow ugc">support guards</a>. Wrote much a much better README guide (I guess) and also documented it more.</p>
<p>The only thing I removed from v0 is  the <code>...</code> syntax as it introduced all variables in scope and it was mostly a pain since elixir 1.5. So now you have to be explicit on what you bind.</p>
<p>Hope the guide explains a bit better where this library fits and how it could be used.</p>
<p>&lt;3</p>
<p>Edit. Forgot to mention, for <a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a>, in the example using guards from the readme, <code>expat def</code> just expands the inner patterns and collects (anding) any guards produced by them, and finally just ands those with any from the function definition. <a href="https://github.com/vic/expat/blob/8019ad4/lib/expat/macro.ex#L136" rel="noopener nofollow ugc">here’s the code</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73083" data-batch-url="/posts/batch_likers">
                        7
                      </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/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-73083" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73083"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="73176" data-post-id="73176">
  <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="18" 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>Hey, good news, I’ve just released v1.0, I did a major rewrite as I really wanted (and needed) it to support guards.</p>
</blockquote>
</aside>
<blockquote>
<p>Since expat v1.0 it’s now possible to use guards on your pattern definitions, and they will be expanded at the call-site.</p>
</blockquote>
<p>Whoo!  This now entirely replaces my purposefully gimped (since it was a standards suggestion and not a real library) library of <a href="https://github.com/OvermindDL1/defguard/blob/master/test/test_helper.exs" rel="noopener nofollow ugc"><code>defguard</code></a>.  ^.^</p>
<p>Although I think I still like the syntax of mine better, I just think that it should be built into elixir instead of the highly gimped-in-comparison <code>defguard</code> that it recently got (though it could be expanded in the future…)</p>
<p>I like how you encourage your’s as a constructor too, do the guards apply on that properly?  <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="73176" 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/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-73176" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73176"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="73230" data-post-id="73230">
  <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="19" 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>do the guards apply on that properly?</p>
</blockquote>
</aside>
<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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73230" 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/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-73230" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73230"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="73268" data-post-id="73268">
  <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="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>Lol, I saw it.  ^.^</p>
<p>Have you thought about 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?  (Mine is purposefully incomplete because I overrode <code>def</code> to do it, which is not shibby, but it was purely an example anyway).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="73268" 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/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-73268" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="73268"
                     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 #20"></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=3">Load more posts (12 remaining)</a>
</div></template></turbo-stream>