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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kenny-evitt" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kenny-evitt
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Great points!</p>
<p>With respect to documenting types declared with this kind of code, one could add a <code>@typedoc</code> attribute, or, possibly even better, add a ‘types’ section-comment for the relevant module.</p>
<p>I’m pretty satisfied with all of the identified options now.</p>
<p>But I’m still curious as to whether it’s <em>possible</em> (somehow) to write a <code>union_type/1</code> macro that would work like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@type key :: union_type(@keys)
</code></pre>
<p>It did seem tricky and maybe because we’re passing a module attribute to the macro instead of literals.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="191984" 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/dynamically-generate-typespecs-from-module-attribute-list/7078/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-191984" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="191984"
                     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="191989" data-post-id="191989">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="kenny-evitt" data-post="13" data-topic="7078">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/k/e47774/48.png" class="avatar"> kenny-evitt:</div>
<blockquote>
<p>But I’m still curious as to whether it’s <em>possible</em> (somehow) to write a <code>union_type/1</code> macro that would work like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@type key :: union_type(@keys)
</code></pre>
</blockquote>
</aside>
<p>As said it’s not possible …</p>
<aside class="quote no-group" data-username="Eiji" data-post="10" data-topic="7078">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/eiji/48/36743_2.png" class="avatar"> Eiji:</div>
<blockquote>
<p>In both <code>@spec</code> and <code>@type</code> you need to wrap everything in <code>unquote</code> call. Without that instead of calling function/macro the <code>AST</code> of such call would be stored:</p>
</blockquote>
</aside>
<p><code>@spec</code> and <code>@type</code> accepts any valid expression and stores it’s <code>AST</code> representation. No matter what you call they would store an <code>AST</code> of call.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; quote do
iex&gt;   my_func()
iex&gt; end
{:my_func, [], []}
# this is just tuple (AST of call)
# since it's not call there is nothing called
</code></pre>
<p>Since we are working on <code>quoted</code> expressions to add something inside quoted expression you need to use <a href="https://hexdocs.pm/elixir/Kernel.SpecialForms.html#unquote/1" rel="noopener nofollow ugc">unquote(expr)</a> call.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="191989" 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/dynamically-generate-typespecs-from-module-attribute-list/7078/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-191989" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="191989"
                     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="191993" data-post-id="191993">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kenny-evitt" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kenny-evitt
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<blockquote>
<p>In both  <code>@spec</code>  and  <code>@type</code>  you need to wrap everything in  <code>unquote</code>  call. Without that instead of calling function/macro the  <code>AST</code>  of such call would be stored:</p>
</blockquote>
<p><code>@spec</code>  and  <code>@type</code>  accepts any valid expression and stores it’s  <code>AST</code>  representation. No matter what you call they would store an  <code>AST</code>  of call.</p>
</blockquote>
<p>Ahhh – that makes sense!</p>
<p>Thanks for repeating yourself, with enough of a different emphasis, for me to appreciate your original point. <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="191993" 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/dynamically-generate-typespecs-from-module-attribute-list/7078/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-191993" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="191993"
                     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="264722" data-post-id="264722">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="axelson" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/axelson/120/26351_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  axelson
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Scenic Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is a great snippet! Here’s a function form of this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule TypeUtils do
  # https://forum.elixirforum.com/t/dynamically-generate-typespecs-from-module-attribute-list/7078/5
  def list_to_typespec(list) when is_list(list) do
    Enum.reduce(list, &amp;{:|, [], [&amp;1, &amp;2]})
  end
end
</code></pre>
<p>Usage example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  @statuses [:not_started, :completed]
  @type status :: unquote(TypeUtils.list_to_typespec(@statuses))
</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="264722" data-batch-url="/posts/batch_likers">
                        5
                      </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/dynamically-generate-typespecs-from-module-attribute-list/7078/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-264722" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="264722"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="339742" data-post-id="339742">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="axelson" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/axelson/120/26351_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  axelson
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Scenic Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>We’ve also now extracted this into a little library:</p>
<p><a href="https://github.com/felt/union_typespec" class="onebox" target="_blank" rel="noopener nofollow">https://github.com/felt/union_typespec</a></p>
<p>One of the main reasons to extract it was to avoid extra compile-time dependencies.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="339742" 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/dynamically-generate-typespecs-from-module-attribute-list/7078/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-339742" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="339742"
                     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="355101" data-post-id="355101">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kenny-evitt" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kenny-evitt
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I just checked out the library <img src="https://forum.elixirforum.com/images/emoji/apple/heart.png?v=15" title=":heart:" class="emoji" alt=":heart:" loading="lazy" width="20" height="20"></p>
<p>Dreams of transclusion in Xanadu <img src="https://forum.elixirforum.com/images/emoji/apple/innocent.png?v=15" title=":innocent:" class="emoji" alt=":innocent:" 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="355101" 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/dynamically-generate-typespecs-from-module-attribute-list/7078/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-355101" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="355101"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>