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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My point is I don’t want to lose the let it crash semantics by replacing it with lots of unnecessary checking code to keep the compiler happy throughout the code base and community libraries adopting bad defensive coding idioms and <strong>still</strong> have essentially the same runtime behaviour.</p>
<p>I like the contract semantics of Elixir, no match results in a crash. I don’t want functions accepting bad input that it has to check to avoid a compiler warning. The responsibility must be pushed to the caller, not the callee.</p>
<p>I have already played devils advocate and shown how good intentions can lead to bad outcomes.</p>
<p>The one thing we actually want out of the compiler checks is to identify root causes of problems. If the problem appears to be an unhandled case, developers will add the catchall clause. So now we silence the compiler and the developer <em>feels</em> like they did some good. However, depending on where this case expression lives, what they just did is potentially fail to address the root cause at a boundary layer. If it’s in a boundary or santisation layer then great they addressed bad external input, however if it’s further down the call graph where library authors code defensively to handle bad input then the developer has not addressed the root cause, and has allowed unsanitised input to flow throughout the code.</p>
<p>The worst outcome is that defensive coding everywhere hides the root cause and shifts the effort into fixing the wrong code. We ultimately want the boundary layer to deal with santisation and the sad paths and the core of our applications and business logic to deal with the happy path.</p>
<p>Hence anything the compiler can do to pinpoint the origin of the unsanitised / unprovable input further up the call graph helps developers put the defense’s in the right place.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294541" 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/type-system-updates-moving-from-research-into-development/56827/136">Post #135</a>
	                </div>
	            </div>
              <div id="likers-container-294541" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294541"
                     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 #135"></div>
  </section>
</div>
    <div class="postbit" id="294544" data-post-id="294544">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="adw632" data-post="136" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/a/9d8465/48.png" class="avatar"> adw632:</div>
<blockquote>
<p>depending on where this case expression lives, what they just did is potentially fail to address the root cause at a boundary layer. If it’s in a boundary or santisation layer then great they addressed bad external input, however if it’s further down the call graph where library authors code defensively to handle bad input then the developer has not addressed the root cause, and has allowed unsanitised input to flow throughout the code.</p>
</blockquote>
</aside>
<p>Can you provide an example or even sort of pseudocode outline of what you mean here?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294544" 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/type-system-updates-moving-from-research-into-development/56827/137">Post #136</a>
	                </div>
	            </div>
              <div id="likers-container-294544" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294544"
                     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 #136"></div>
  </section>
</div>
    <div class="postbit" id="294546" data-post-id="294546">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sorry to butt in when you didn’t ask me, but your <a class="mention" href="/u/adw632" rel="nofollow">@adw632</a> quote is exactly what I was thinking (so long as I’m understanding him).  I had an actual example of this last week I did share but can’t find my post.</p>
<p>In short, I have a bunch of checkboxes with <code>phx-click</code>s on them.  There is no form as they are dumb toggles so there are no changesets for validation.  My <code>handle_event</code> looks like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def handle_event("toggle", %{"value" =&gt; value}, socket) do
  case value do
    "true" -&gt; {:noreply, assign(socket, :thing, on(socket.assigns.thing)}
    "false" -&gt; {:noreply, assign(socket, :thing, off(socket.assigns.thing)}
  end
end
</code></pre>
<p>Nothing explicit in <em>my</em> code would let a third case to be hit (ie, I’m relying on an html form control to do the right thing), but a third case <em>could</em> be hit if some nefarious user is manually sending something other than <code>"true"</code> or <code>"false"</code>.  In that case I would want it to crash (as opposed to handling it) and I was thinking that was the point of <code>???</code>: to explicitly say “I know this can crash at runtime and I don’t care.”  Re-reading comments here, though, I’m not so sure (especially <a class="mention" href="/u/dimitarvp" rel="nofollow">@dimitarvp</a>’s comments around making implicit explicit a non-goal).  I guess I’m just not understanding the runtime implications of it (if there even are any).  I’m happy to sit and keep reading and re-reading comments until I get it, though.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294546" 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/type-system-updates-moving-from-research-into-development/56827/138">Post #137</a>
	                </div>
	            </div>
              <div id="likers-container-294546" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294546"
                     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 #137"></div>
  </section>
</div>
    <div class="postbit" id="294551" data-post-id="294551">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>We may be speaking past each other somewhat. I certainly agree with you that losing let it crash semantics would be a Bad Thing. Where I either disagree or am misunderstanding you is in the bits that follow:</p>
<blockquote>
<p>… by replacing it with lots of unnecessary checking code to keep the compiler happy throughout the code base and community libraries adopting bad defensive coding idioms and <strong>still</strong> have essentially the same runtime behaviour</p>
</blockquote>
<p>How would the proposed <code>???</code>/<code>unreadable!</code> make anything worse than the <em>status quo?</em> (Keeping in mind that the discussion here is on introducing a <em>gradual</em> type checker <em>gradually</em>, and these various proposals are just thought experiments on how best to support new capabilities that the type checker might give us while respecting existing code and idioms.)</p>
<p>Current behavior: I write a <code>case</code> that checks the things I expect. If something I don’t expect is passed in, it blows up.</p>
<p>Hypothetical type checking behavior: I write a <code>case</code> inside a function with a type signature that fully defines the set of inputs, so nothing changes and I only handle the things I expect. OR I write a <code>case</code> that is dealing with unbounded input of some kind (maybe <code>dynamic()</code>), and so I throw a <code>_ -&gt; ???</code> in there to indicate that I don’t expect that to happen, but if it does, just blow up.</p>
<p>What I’m missing is the way in which the above at all “encourages bad practices” or is “defensive programming.”</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294551" 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/type-system-updates-moving-from-research-into-development/56827/139">Post #138</a>
	                </div>
	            </div>
              <div id="likers-container-294551" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294551"
                     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 #138"></div>
  </section>
</div>
    <div class="postbit" id="294560" data-post-id="294560">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I apologize for the dumb question, but in terms of architecture, where is the boundary layer in a phoenix app? My assumption is that your example fits with the statement:</p>
<aside class="quote no-group" data-username="andrewh" data-post="136" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
 andrewh:</div>
<blockquote>
<p>If it’s in a boundary or santisation layer then great they addressed bad external input</p>
</blockquote>
</aside>
<p>but that if the Phoenix team introduced some means of overriding things such that calling handle_event that raises an error for no value or no type matching in the case statement silently does some mitigation to prevent a crash then it would fall into</p>
<aside class="quote no-group" data-username="andrewh" data-post="136" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
 andrewh:</div>
<blockquote>
<p>however if it’s further down the call graph where library authors code defensively to handle bad input then the developer has not addressed the root cause, and has allowed unsanitised input to flow throughout the code.</p>
</blockquote>
</aside>
<p>I don’t really have any idea how the Phoenix team (or anyone else, I don’t mean to pick on them) could implement such a strategy, but I think that is <span class="mention">@andrewh</span>’s concern. But I also think maybe I’m misunderstanding.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294560" 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/type-system-updates-moving-from-research-into-development/56827/140">Post #139</a>
	                </div>
	            </div>
              <div id="likers-container-294560" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294560"
                     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 #139"></div>
  </section>
</div>
    <div class="postbit" id="294567" data-post-id="294567">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="stevensonmt" data-post="140" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stevensonmt/48/20503_2.png" class="avatar"> stevensonmt:</div>
<blockquote>
<p>I apologize for the dumb question, but in terms of architecture, where is the boundary layer in a phoenix app?</p>
</blockquote>
</aside>
<p>Typically a context module is where things can fail..</p>
<p>Santizing external user input and applying it to Ecto repo queries or changesets for the external database or interfacing with something else external.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294567" 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/type-system-updates-moving-from-research-into-development/56827/141">Post #140</a>
	                </div>
	            </div>
              <div id="likers-container-294567" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294567"
                     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 #140"></div>
  </section>
</div>
    <div class="postbit" id="294568" data-post-id="294568">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for your post.</p>
<p>The answer depends on the context. The example of handling all possible case values using something like ??? or <code>!unreachable</code>, <code>!oops</code> vs only handling what you care about have practically identical runtime behaviour.</p>
<p>However at compile time if an error/warning indicates that some case expression is “not exhaustive” the developer may likely see the problem being the case expression rather than much further up the call graph where input ought to have been sanitized earlier. You definitely want to catch these occurances and not silence them prematurely by being exhaustive BECAUSE the problem actually lies elsewhere.</p>
<p>However if the case expression (or some function call) actually forms part of the role of santizing values from boundary layers then you still want the heads up from the compiler, however you may choose to silence these by handling the missing case explicitly (catching actual sanitization problems, missing values, typos etc) OR you may want to express that “its ok I don’t want or need to write more code to silence the compiler and I really want to let it crash here, please don’t complain here again”.</p>
<p>We have discussed some notions for expressing that something should never happen however it is not quite there yet IMO because we probably do need to handle  “stfu compiler” from the caller site where we don’t want to write more code and we acknowledge that we want it to crash.</p>
<p>What I don’t want is defensively coding the sad path for every function signature and every case statement in the core logic of my app (aka “pipeland”)  nor do I want every hex utility package I include using “defensive” idioms as “best practice” because it will prematurely silence problems that <em>ought</em> to be handled by the caller at a layer or more above.</p>
<p>If we decide that we do wish to explicitly handle cases and function signatures as a programmer aid (perhaps because of deprecations), then I think we do need a language feature to signal that although we are handling this function signature or case expression we still want any call graph that arrives here to be flagged as a problem on the CALLER, and ideally the entire call graph being implicated starting from the root so that the origin of the problem is handled as far up the call graph as possible.</p>
<p>For this reason the compiler should list the call graph paths that are implicated in the issue of not meeting the supported type and value constraints.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294568" 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/type-system-updates-moving-from-research-into-development/56827/142">Post #141</a>
	                </div>
	            </div>
              <div id="likers-container-294568" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294568"
                     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 #141"></div>
  </section>
</div>
    <div class="postbit" id="294569" data-post-id="294569">
  <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
                    <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>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="adw632" data-post="142" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/a/9d8465/48.png" class="avatar"> adw632:</div>
<blockquote>
<p>The answer depends on the context. The example of handling all possible case values using something like ??? or <code>!unreachable</code>, <code>!oops</code> vs only handling what you care about have practically identical runtime behaviour.</p>
</blockquote>
</aside>
<p>I would say there is another aspect here: communication between humans and your future self. Imagine that you find this code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">case some_fun() do
  :foo -&gt; ...
  :bar -&gt; ...
end
</code></pre>
<p>And <code>some_fun</code> may also return <code>:baz</code>. There are at least two possible interpretations:</p>
<ol>
<li>You know it could return <code>:baz</code> but you don’t care</li>
<li>When you implemented it, <code>:baz</code> was not a possible return value</li>
</ol>
<p>If you add something such as <code>:baz -&gt; ???</code>, then you are removing the ambiguity and explicitly encoding a decision. Which is why some interpret it as augmented let it crash.</p>
<aside class="quote no-group" data-username="adw632" data-post="142" data-topic="56827">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/a/9d8465/48.png" class="avatar"> adw632:</div>
<blockquote>
<p>If we decide that we do wish to explicitly handle cases and function signatures as a programmer aid (perhaps because of deprecations), then I think we do need a language feature to signal that although we are handling this function signature or case expression we still want any call graph that arrives here to be flagged as a problem on the CALLER, and ideally the entire call graph being implicated starting from the root so that the origin of the problem is handled as far up the call graph as possible.</p>
</blockquote>
</aside>
<p>Those are somewhat orthogonal discussions. The type system is expressive so we can indeed surface most of these decisions up. We hope that, in many scenarios, the type system will know exactly the subset of return values that match your input. So it isn’t like you will have to handle those decisions <em>everywhere</em>. I think this is an important nuance that may be getting lost in the conversation. This discussion is more about when the return values are based on runtime behaviour and then there is no way to disambiguate and surface up at compile-time.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294569" 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/type-system-updates-moving-from-research-into-development/56827/143">Post #142</a>
	                </div>
	            </div>
              <div id="likers-container-294569" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294569"
                     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 #142"></div>
  </section>
</div>
    <div class="postbit" id="294575" data-post-id="294575">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="adw632" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  adw632
                  </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="143" data-topic="56827">
<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 would say there is another aspect here: communication between humans and your future self. Imagine that you find this code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">case some_fun() do
  :foo -&gt; ...
  :bar -&gt; ...
end
</code></pre>
<p>And <code>some_fun</code> may also return <code>:baz</code>. There are at least two possible interpretations:</p>
<ol>
<li>You know it could return <code>:baz</code> but you don’t care</li>
<li>When you implemented it, <code>:baz</code> was not a possible return value</li>
</ol>
<p>If you add something such as <code>:baz -&gt; ???</code>, then you are removing the ambiguity and explicitly encoding a decision. Which is why some interpret it as augmented let it crash.</p>
</blockquote>
</aside>
<p>Yes I agree that communication and intents is very important.</p>
<p>Handling the case <code>:baz -&gt; ???</code> may be due to many factors, some specific state passed to <code>some_func()</code> that is now permitted but previously wasn’t, or it could just be a more nuanced return type but either way it is an API surface change/versioning and that is a topic that is also worthy of another whole conversation.</p>
<p>This example however goes well beyond types because here we are looking at value semantics, even a static typed language won’t automatically handle a new case.</p>
<p>That said, the compiler should identify a non exhaustive case expression, then it is up to the developer how they wish to handle it, either explicitly handling the new cases, or making sure their inputs conform to the possible return value cases they are prepared to handle or as the very last resort, declaring a catch all so the compiler accepts this without generating further noise.</p>
<p>Once the compiler is silenced with a catchall clause the developer forever gets the silent treatment from the compiler.</p>
<p>This means a change from some API v1.0 to v1.1 may catch a few things but v1.1 to v1.2 will silence potential issues due to catch alls. This is why I don’t think defensive catch all approaches are a good idiom in the face of changes and explicit is far better for being defensive so you can detect and then handle future return values as code evolves, especially changes in external 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="294575" 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/type-system-updates-moving-from-research-into-development/56827/144">Post #143</a>
	                </div>
	            </div>
              <div id="likers-container-294575" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294575"
                     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 #143"></div>
  </section>
</div>
    <div class="postbit" id="294581" data-post-id="294581">
  <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
                    <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>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Let’s see if I got it right. Your concern is that something like <code>_ -&gt; ???</code> may promote defensive code that is actually worse than today because:</p>
<ol>
<li>It doesn’t help at compile-time</li>
<li>It is more verbose than today with no benefits on runtime or intent</li>
</ol>
<p>You are actually ok with <code>:bar -&gt; ???</code>. But adding something like <code>???</code> should come with the caveat that it should not be used in pokemon clauses. If so, that’s a good point and we are in agreement.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="294581" 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/type-system-updates-moving-from-research-into-development/56827/145">Post #144</a>
	                </div>
	            </div>
              <div id="likers-container-294581" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="294581"
                     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 #144"></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/56827/load_more?page=15">Load more posts (24 remaining)</a>
</div></template></turbo-stream>