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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="christhekeele" data-post="28" data-topic="71220">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ File.t -&gt; binary
def load_resource(%File{}), do: # return a binary

$ URI.t -&gt; Stream.t
def load_resource(%URI{}), do: # return a stream
</code></pre>
</blockquote>
</aside>
<p>In the very same moment I see types like this, this means one of 2 things to me:</p>
<ol>
<li>You actually want <code>load_ressource_from_file</code> and <code>load_ressource_from_url</code></li>
<li>You want to find an abstraction over the result type, that covers all possible cases, and can be used the same at the call site</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367063" 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/a-case-for-inline-type-annotations/71220/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-367063" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367063"
                     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 #31"></div>
  </section>
</div>
    <div class="postbit" id="367070" data-post-id="367070">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="smueller" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/smueller/120/3857_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  smueller
                    <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>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="30" data-topic="71220">
<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>I found this particularly confusing in the other example you posted</p>
</blockquote>
</aside>
<p>That wasn’t my example, it was someone else’s (<a class="mention" href="/u/lud" rel="nofollow">@lud</a>) that posted with the intent to be verbose, and I illustrated that it could be less verbose with modern constructs like type aliases. I personally wouldn’t ever write code this confusing in any language, please don’t attribute the example to me.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="30" data-topic="71220">
<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>What you are proposing is equivalent to saying this Kotlin code</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">fun handle(value: String): String = value.uppercase()
fun handle(value: Int): Boolean = value % 2 == 0
fun handle(value: List&lt;Any&gt;): Int = value.size
</code></pre>
<p>should have a repeating type signature, which is clearly not true as seen above, but it would also lead to repeating return types:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">fun handle(value: String | Int | List&lt;Any&gt;): String | Boolean | Int =
</code></pre>
<p>which comes with a massive loss of precision as you no longer capture the information that a “Boolean” is returned only if you gave it an “Int” type.</p>
</blockquote>
</aside>
<p>This is not what I suggested or implied. In Swift you can write:</p>
<pre data-code-wrap="swift"><code class="lang-swift">typealias Transportable = Codable &amp; Hashable

struct PushReply&lt;Payload: Transportable&gt;: Transportable {
    var joinRef: String?
    var ref: String?
    var topic: String
    var event: String?
    var container: Container&lt;Payload&gt;
    
    struct Container&lt;ContainerPayload: Transportable&gt;: Transportable {
        var response: ContainerPayload
        var status: String
    }
}
</code></pre>
<p>The typealias allows you to combine types and then cleanly represent that combination in function signatures and structures, rather than repeating the individual types themselves everywhere. While this is not <em>exactly</em> the same as your example returning one of the following statuses <code>$ type payment_status = :trial | {:success, metadata} | {:overdue, metadata}</code> (essentially and vs or) but the benefit of avoiding verbosity still remains.</p>
<p>By the way, your Kotlin code makes alot of sense to me:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">fun handle(value: String): String = value.uppercase()
fun handle(value: Int): Boolean = value % 2 == 0
fun handle(value: List&lt;Any&gt;): Int = value.size
</code></pre>
<p>And if I were to write it intuitively in elixir with inline types, it would be something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def handle(value :: Int) :: String, do: String.upcase(value)
def handle(value :: String) :: Boolean, do: rem(value, 2) == 0
def handle(value :: List) :: Int, do: length(value)
</code></pre>
<p>What would it look like with the proposed <code>$</code> notation?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367070" 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/a-case-for-inline-type-annotations/71220/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-367070" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367070"
                     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 #32"></div>
  </section>
</div>
    <div class="postbit" id="367073" data-post-id="367073">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="smueller" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/smueller/120/3857_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  smueller
                    <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>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Hex-Core-Team quote-modified" data-username="wojtekmach" data-post="31" data-topic="71220">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/48/999_2.png" class="avatar"> wojtekmach:</div>
<blockquote>
<p>Reading this code for the first time, my immediate reaction is:</p>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">def hostname(%URI{host: host} :: URI | String?) :: String?, do: host
</code></pre>
</blockquote>
<pre><code>         ^^^^^^^^^^^^^^^^    ^^^ ^^^^^^^^^
</code></pre>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir"></code></pre>
</blockquote>
<p>We’re already pattern matching on a <code>%URI{}</code> so writing <code>URI</code> <em>again</em> feels redundant but writing <code>| String?</code> is confusing, it’s not a nullable string, we’ve already established it’s an URI.</p>
</blockquote>
</aside>
<p>Again worth repeating this is not my code, and you’re critiquing as if someone would actually try to write this? I’d fire someone immediately if I saw this commit, and if an LLM spit this out I would call up Sam Altman myself to complain.</p>
<p>Let’s move on from this code since it seems to have transformed into a red herring of invalidation, which is disingenuous to the post itself and the concerns that have been raised.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367073" 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/a-case-for-inline-type-annotations/71220/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-367073" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367073"
                     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 #33"></div>
  </section>
</div>
    <div class="postbit" id="367075" data-post-id="367075">
  <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>If the code you modified is not your actual suggestion on how you would type those functions, then you still have not answered how you would actually type those examples. <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"> Otherwise, the only signature you posted so far is the one-line <code>inc</code> function, which we should all agree is not representative of the majority of the written code out there.</p>
<p>So in order to be concrete:</p>
<ol>
<li>
<p>How would you type the <code>log_payment_status</code> function? In your reply, you repeated the type signature and made the function partially match the content of the aliases, which as I explained in my previous reply, it is not natural to other languages, so it is confusing and repetitive (even if we completely disregard the proposed hostname function).</p>
</li>
<li>
<p>How would you type the original <code>hostname</code> function then? Remember that type signatures cannot replace pattern matching and guards, as they are more expressive than type signatures. We can pattern match on integers, empty lists, sequences, binaries, and none of those can be expressed in any of the type systems of the languages above.</p>
</li>
</ol>
<p>We can look at Swift and Kotlin code and translate that to Elixir but that’s not the task at hand. The job is to type existing Elixir code and support the language idioms. So <strong>how would you type the examples that have already been shown in this thread?</strong></p>
<p>For completeness, here is how the hostname function would be typed with our proposed types:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ URI.t() or binary() or nil -&gt; binary() or nil
def hostname(%URI{host: host}), do: host
def hostname(url) when is_binary(url), do: hostname(URI.parse(url))
def hostname(nil), do: nil
</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="367075" 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/a-case-for-inline-type-annotations/71220/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-367075" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367075"
                     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 #34"></div>
  </section>
</div>
    <div class="postbit" id="367078" data-post-id="367078">
  <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>Even better, here is the relatively small URI module from Elixir. Can you go through every function and type them according to your proposal? <a href="https://github.com/elixir-lang/elixir/blob/main/lib/elixir/lib/uri.ex" class="inline-onebox" rel="nofollow">elixir/lib/elixir/lib/uri.ex at main · elixir-lang/elixir · GitHub</a> - the new type system would be quite similar to the existing specs, so that’s a good reference, but I can write a complete version as a follow up to yours. This will allow us to move the discussion into actual working code, rather than one-liners or fictional examples. Otherwise, we will all be guessing what you actually meant, which is not fair to you (nor anyone else).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367078" 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/a-case-for-inline-type-annotations/71220/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-367078" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367078"
                     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 #35"></div>
  </section>
</div>
    <div class="postbit" id="367082" data-post-id="367082">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>That wasn’t my example, it was someone else’s (<a class="mention" href="/u/lud" rel="nofollow">@lud</a>) that posted with the intent to be verbose, and I illustrated that it could be less verbose with modern constructs like type aliases. I personally wouldn’t ever write code this confusing in any language, please don’t attribute the example to me.</p>
</blockquote>
<p>I also gave an example with typealiases, before anybody else, to go partially in your direction.</p>
<blockquote>
<p>Again worth repeating this is not my code, and you’re critiquing as if someone would actually try to write this? I’d fire someone immediately if I saw this commit, and if an LLM spit this out I would call up Sam Altman myself to complain.</p>
</blockquote>
<p>This is <a href="https://forum.elixirforum.com/t/a-case-for-inline-type-annotations/71220/24" rel="nofollow">your code</a> though, a variation on mine. And while I agree that using type aliases makes it look more correct, it does not change the fact that a clause declares <code>%URI{} :: URI | String?</code> which is strange.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367082" 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/a-case-for-inline-type-annotations/71220/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-367082" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367082"
                     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 #36"></div>
  </section>
</div>
    <div class="postbit" id="367153" data-post-id="367153">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="smueller" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/smueller/120/3857_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  smueller
                    <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>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="smueller" data-post="25" data-topic="71220">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/smueller/48/3857_2.png" class="avatar"> smueller:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ typealias PaymentStatus = :trial | {:success, metadata} | {:overdue, metadata}
def log_payment_status(:trial :: PaymentStatus) do
def log_payment_status({:success, metadata} :: PaymentStatus) do
def log_payment_status({:overdue, metadata} :: PaymentStatus) do
</code></pre>
</blockquote>
</aside>
<p><a class="mention" href="/u/lud" rel="nofollow">@lud</a> I agree that you brought up typealiases (even before I mentioned) and I’m aligned with your thinking and examples – I should have called out this alignment more, instead of focusing on just the counter-intuitiveness of how this example’s signature was written.</p>
<p>I think Jose derailed a bit by stating <code>I found this particularly confusing in the other example you posted</code> and <code>Not only it is repetitive and confusing, it also means we are incapable of expressing function overloads</code> when it wasn’t my original code, and the only modification was going from <code>String.t() | nil</code> to <code>String?</code> to illustrate optional types will improve clarity and conciseness.</p>
<aside class="quote no-group">
<blockquote>
<p>it does not change the fact that a clause declares <code>%URI{} :: URI | String?</code> which is strange</p>
</blockquote>
</aside>
<p>Do we all agree that this <code>%URI{host: host} :: URI.t()) :: String.t() | nil</code> is more concise+readable with optional type sugar (<code>?</code>) and typealiases, as you first mentioned? I would think the answer is universally “yes”.</p>
<p>The real debate is that even with modern syntax (typealiases, optional type <code>String?</code>, and potentially others), do inline types still not fit with elixir? Is <code>$</code> just that much better for this language? Let’s continue on that path..</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367153" 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/a-case-for-inline-type-annotations/71220/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-367153" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367153"
                     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 #37"></div>
  </section>
</div>
    <div class="postbit" id="367155" data-post-id="367155">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="smueller" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/smueller/120/3857_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  smueller
                    <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>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Great suggestion Jose, here is <code>uri.ex</code> with just typealiases and optional types. There are a few other modern constructs that could potentially improve even more, but I think this is aligned to what’s possible in the current scope of work.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule URI do
  @moduledoc """
  Utilities for working with URIs.
  """

  # Type aliases for better readability
  typealias Scheme :: String?
  typealias Host :: String?
  typealias Port :: non_neg_integer?
  typealias Path :: String?
  typealias Query :: String?
  typealias Fragment :: String?
  typealias Userinfo :: String?
  typealias URIString :: String
  typealias EncodingType :: :www_form | :rfc3986
  typealias QueryMap :: %{String =&gt; String}
  typealias QueryEnum :: Enumerable.t()
  typealias QueryPair :: {String, String}
  typealias Predicate :: (byte -&gt; boolean)
  typealias Authority :: String?

  @derive {Inspect, optional: [:authority]}
  defstruct [:scheme, :authority, :userinfo, :host, :port, :path, :query, :fragment]

  # Core URI functions
  def default_port(scheme :: String) :: Port
  def default_port(scheme :: String, port :: non_neg_integer) :: :ok

  # Query encoding/decoding
  def encode_query(enumerable :: QueryEnum, encoding :: EncodingType \\ :www_form) :: String
  def decode_query(query :: String, map :: QueryMap \\ %{}, encoding :: EncodingType \\ :www_form) :: QueryMap
  def query_decoder(query :: String, encoding :: EncodingType \\ :www_form) :: Enumerable.t()

  # Character classification
  def char_reserved?(character :: byte) :: boolean
  def char_unreserved?(character :: byte) :: boolean
  def char_unescaped?(character :: byte) :: boolean

  # Encoding/decoding
  def encode(string :: String, predicate :: Predicate \\ &amp;char_unescaped?/1) :: String
  def encode_www_form(string :: String) :: String
  def decode(uri :: String) :: String
  def decode_www_form(string :: String) :: String

  # URI creation and parsing
  def new(uri :: t | URIString) :: {:ok, t} | {:error, String}
  def new!(uri :: t | URIString) :: t
  def parse(uri :: t | String) :: t

  # URI manipulation
  def to_string(uri :: t) :: String
  def merge(base :: t | String, rel :: t | String) :: t
  def append_query(uri :: t, query :: String) :: t
  def append_path(uri :: t, path :: String) :: t

  # Private helper functions
  defp encode_kv_pair({key, _} :: QueryPair, _encoding :: EncodingType) when is_list(key)
  defp encode_kv_pair({_, value} :: QueryPair, _encoding :: EncodingType) when is_list(value)
  defp encode_kv_pair({key, value} :: QueryPair, :rfc3986 :: EncodingType) :: String
  defp encode_kv_pair({key, value} :: QueryPair, :www_form :: EncodingType) :: String

  defp decode_query_into_map(query :: String, map :: QueryMap, encoding :: EncodingType) :: QueryMap
  defp decode_query_into_dict(query :: String, dict :: any, encoding :: EncodingType) :: any

  defp decode_next_query_pair("" :: String, _encoding :: EncodingType) :: nil
  defp decode_next_query_pair(query :: String, encoding :: EncodingType) :: {QueryPair, String}?

  defp decode_with_encoding(string :: String, :www_form :: EncodingType) :: String
  defp decode_with_encoding(string :: String, :rfc3986 :: EncodingType) :: String

  defp percent(char :: byte, predicate :: Predicate) :: String
  defp hex(n :: byte) :: byte when n &lt;= 9
  defp hex(n :: byte) :: byte

  defp unpercent(binary :: String, acc :: String, spaces :: boolean) :: String
  defp hex_to_dec(n :: byte) :: byte?

  defp uri_from_map(%{path: ""} = map :: map) :: t
  defp uri_from_map(map :: map) :: t

  defp parse_string(string :: String) :: t
  defp nilify_query("?" &lt;&gt; query :: String) :: String
  defp nilify_query(_other :: any) :: nil

  defp split_authority("" :: String) :: {nil, nil, nil, nil}
  defp split_authority("//" :: String) :: {Authority, nil, String, nil}
  defp split_authority("//" &lt;&gt; authority :: String) :: {Authority, Userinfo?, Host?, Port?}

  defp nilify("" :: String) :: nil
  defp nilify(other :: any) :: any

  defp merge_paths(nil :: nil, rel_path :: Path) :: Path
  defp merge_paths(_ :: Path, "/" &lt;&gt; _ = rel_path :: Path) :: Path
  defp merge_paths(base_path :: Path, rel_path :: Path) :: Path

  defp remove_dot_segments_from_path(nil :: nil) :: nil
  defp remove_dot_segments_from_path(path :: String) :: String

  defp path_to_segments(path :: String) :: [String | atom]
  defp remove_dot_segments(segments :: [String | atom], acc :: [String | atom]) :: [String | atom]

  defp join_reversed_segments([:/] :: [atom]) :: String
  defp join_reversed_segments(segments :: [String | atom]) :: String
end

defimpl String.Chars, for: URI do
  def to_string(uri :: URI.t()) :: String

  defp extract_authority(%{host: nil, authority: authority} :: URI.t()) :: String?
  defp extract_authority(%{host: host, userinfo: userinfo, port: port} :: URI.t()) :: iodata
end
</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="367155" 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/a-case-for-inline-type-annotations/71220/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-367155" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367155"
                     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 #38"></div>
  </section>
</div>
    <div class="postbit" id="367158" data-post-id="367158">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I don’t see how the <code>?</code> could make sense.  Is <code>URI | String?</code> supposed to mean <code>URI | String | nil</code> or <code>URI | (String | nil)</code>?  Because it reads like the latter but works like the former, no?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367158" 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/a-case-for-inline-type-annotations/71220/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-367158" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367158"
                     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 #39"></div>
  </section>
</div>
    <div class="postbit" id="367167" data-post-id="367167">
  <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>Thank you <a class="mention" href="/u/smueller" rel="nofollow">@smueller</a> for providing this example. However, I must point out that you are not fully showcasing what you proposed, given several functions had their clauses elided, such as <code>new</code>, <code>new!</code>, <code>parse</code>, <code>remove_dot_segments</code>, <code>merge</code>, <code>hex_to_dec</code>, and <code>unpercent</code>.</p>
<p>I’d love if you could actually annotate the existing clauses in the URI module, at least for these functions, showing all clauses alongside patterns and guards (you can elide the parts inside the do-block with … for conciseness). It is important to preserve the clauses for inline annotations because one of the arguments against them is that they get repetitive. Otherwise, you are effectively keeping them separate from the existing code, which I must agree looks really good. <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<hr>
<p>Besides the above, here is a question you should answer: do you agree with the previous comment by Wojtek and myself, which said that the following clause is confusing (and I would say semantically invalid), because it says it accepts  <code>URI</code>, <code>String</code> and <code>nil</code>, but in practice that particular clause only deals with <code>String</code>?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def hostname(url :: URI | String?) when is_binary(url) :: String?, do: hostname(URI.parse(url))
                    ^^^^^       ^  ^^^^^^^^^^^^^^^^^^^
</code></pre>
<p>Or do you believe such definitions should be accepted? I am asking semantically, disregard the syntax for now.</p>
<hr>
<p>PS: type aliases are part of the type system. I am not convinced about <code>String?</code> though. I think it is worth being more explicit around nil usage, but this is something I can change my mind once we start using the type system in practice and it feels too verbose. Feel free to use it in your example, it is not relevant to the discussion at hand.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367167" 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/a-case-for-inline-type-annotations/71220/42">Post #41</a>
	                </div>
	            </div>
              <div id="likers-container-367167" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367167"
                     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 #41"></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/71220/load_more?page=5">Load more posts (19 remaining)</a>
</div></template></turbo-stream>