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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sodapopcan" data-post="21" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>I was trying to get further involved but now you pinged me, d’oh <img src="https://forum.elixirforum.com/images/emoji/apple/upside_down_face.png?v=15" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>Yeah sorry, thought I missed a nuance because what I think I got didn’t quite add up. Thanks for clarifying. <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>
<aside class="quote no-group" data-username="sodapopcan" data-post="21" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>This is sort of missing the point—if you’ve checked at the boundaries and you’re getting a <code>nil</code> error, your boundary-checking is wrong. The whole point of boundary casting is to get data into a a solid, known shape (ideally a struct AFAIC though whole other convo).</p>
</blockquote>
</aside>
<p>It’s very possible to have an error in the middle of a bigger function to which my answer 99% of the time is “break it apart in smaller functions and still check at their boundaries”. <img src="https://forum.elixirforum.com/images/emoji/apple/person_shrugging.png?v=15" title=":person_shrugging:" class="emoji" alt=":person_shrugging:" 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="325736" 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/guard-clause-on-match-operator/62981/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-325736" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="325736"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="giddie" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/giddie/120/34394_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  giddie
                    <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="sodapopcan" data-post="21" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>You otherwise don’t usually see random <em>type</em> assertions in a <em>function body</em>. I’m actually having a hard time picturing when this would even be useful—why wouldn’t you check it in the function head?</p>
</blockquote>
</aside>
<p>For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def my_func(opts \\ []) do
  {:ok, value} = Keyword.fetch(opts, :my_integer)
end
</code></pre>
<p>Do I really need to split out a separate function just to ensure my value is an integer? I think it would just be <em>nice</em> if I could add a guard clause here on the match operator to quickly make the assertion for peace of mind before moving on. And really, I’m <em>curious</em> about whether it was deliberately left out by design choice. My suspicion is that it was actually left out for reasons of legibility or because of ambiguity in the AST.</p>
<aside class="quote no-group" data-username="sodapopcan" data-post="21" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>your definition of defensive programming is not the “regular” one</p>
</blockquote>
</aside>
<p>I get where you’re coming from. You could be right. What I mean is, one definition is:</p>
<blockquote>
<p>A form of <a href="https://en.wiktionary.org/wiki/defensive_design#English" rel="noopener nofollow ugc">defensive design</a> aiming to ensure the continuing functioning of a piece of <a href="https://en.wiktionary.org/wiki/software#English" rel="noopener nofollow ugc">software</a> in spite of unforeseeable usage of it.<br>
- <a href="https://en.wiktionary.org/wiki/defensive_programming" rel="noopener nofollow ugc">Wikipedia</a></p>
</blockquote>
<p>To me, this is a great description of OTP. And when I write code in Elixir, I aim to write code that makes use of this defensive design by asserting that the data is as expected, knowing that if it’s not the software as a whole will not crash. I consider that programming defensively - the more assertions, the more defensive. But yeah - looking just at my code, I’m not trying to handle all possible error conditions myself if that’s the way we’re defining it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="325882" 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/guard-clause-on-match-operator/62981/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-325882" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="325882"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="giddie" data-post="23" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/giddie/48/34394_2.png" class="avatar"> giddie:</div>
<blockquote>
<p>Do I really need to split out a separate function just to ensure my value is an integer?</p>
</blockquote>
</aside>
<p>Elixir is strongly but not statically typed so I’d say yes you should, and make use of the tools available to us f.ex.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{:ok, price} = KeywordUtil.fetch_integer(opts, :price)

# elsewhere:

defmodule KeywordUtil do
  # NOTE: `Keyword.fetch` already has guards for both arguments.
  def fetch_integer(kw, key) do
    case Keyword.fetch(kw, keys) do
      {:ok, int} when is_integer(int) -&gt; {:ok, int}
      {:ok, val} -&gt; :error
      :error -&gt; :error
    end
  end
end
</code></pre>
<p>Seeing as this is your specific need then I see no reason why you wouldn’t make wrapping helpers.</p>
<p>…Or we should all just use <a href="https://hexdocs.pm/nimble_options/NimbleOptions.html" rel="noopener nofollow ugc"><code>NimbleOptions</code></a>. <img src="https://forum.elixirforum.com/images/emoji/apple/laughing.png?v=15" title=":laughing:" class="emoji" alt=":laughing:" loading="lazy" width="20" height="20"> Because apparently it’s very far from only you-specific need, I needed such wrappers a number of times.</p>
<aside class="quote no-group" data-username="giddie" data-post="23" data-topic="62981">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/giddie/48/34394_2.png" class="avatar"> giddie:</div>
<blockquote>
<p>And really, I’m <em>curious</em> about whether it was deliberately left out by design choice.</p>
</blockquote>
</aside>
<p>IMO because it’s teetering on Elixir trying to imitate a statically typed language in such a case. If you allow guards on assignments you are like 50% of the way there to static typing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="325884" 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/guard-clause-on-match-operator/62981/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-325884" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="325884"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="325928" data-post-id="325928">
  <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>I don’t want to dive too much into this, but I feel your thinking is a little misplaced including what the BEAM does as “defensive.”  It’s not a “wrong” way to think about it I suppose but then it would be more “The BEAM is defensive so we don’t have to be.”</p>
<p>To expand on <a class="mention" href="/u/dimitarvp" rel="nofollow">@dimitarvp</a> without the static typing angel, the idea is that we don’t want to handle errors <em>that we can’t do anything about</em>.  Context matter greatly here!  So taking your example of parsing options, it depends on—among probably other considerations—if you it’s library code or not.  If it’s library code then whether or not you want to break it out into its own function, you should be <code>case</code>ing it and giving the user a better error message than the default “No match” error along the lines of what Dimi is suggesting.  Really I agree wholeheartedly with him that we should all just be using NimbleOptions <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, if this is code you control used by other code that you control then this comes back to what others have said above: you’re handling this at the wrong level.  You’re basically just making better dev errors for yourself which is exactly the type of code The Erlang Way™ discourages.</p>
<p>For example if I have this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def get_user!(id, opts \\ []) do
  preload = Keyword.get(opts, :preload, [])

  User
  |&gt; Repo.get!(id)
  |&gt; Repo.preload(preload)
end
</code></pre>
<p>And this is my callsite in, let’s say, a LiveView:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def mount(%{"id" =&gt; id}, _session, socket) do
  user = get_user!(id, preload: "invalid preload value")

  # ...
end
</code></pre>
<p>The bug is in the LiveView, not <code>get_user</code>.  Having <code>get_user</code> add “extra safety” is pretty useless here.  Once you fix that bug, the checking code will never error again.  Remember we’re talking business logic and not a library here—the value being being provided at the callsite constant, we control it.  Worrying about future uses of the function is jumping firmly into YAGNI territory.  So in the end, the only thing this code is accomplishing is giving better errors <em>in development</em>.  To me this isn’t worth the cost.  I know how to read stacktraces and I would much rather not have to “read around” defensive code everywhere.  As touched on, this is stuff that dialyzer and tests should be responsible for catching.</p>
<p>Lastly, if the code being passed in is untrusted, that is when you want to <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/" rel="noopener nofollow ugc">parse, don’t validate</a>.  Ensure all untrusted data has been <em>cast</em> into safe, expected data <em>before</em> any business function touches it.  This way you can be sure they’ll get the right types and keep their code business-focused.</p>
<p>Again, I’m just trying to answer your initial question.  The link I posted explains it and there is further reading on a mailing list from Joe Armstrong.  But ya, totally free to program how you want—if you’re on a team that wants to write code like that, that’s all good!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="325928" 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/guard-clause-on-match-operator/62981/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-325928" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="325928"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I would love for us someday to formalize on how to approach these kind of situations, because as someone who wrote quite a bit in languages like Kotlin and Java, coming back to elixir after using those I always feel like I need to rearrange my brain <img src="https://forum.elixirforum.com/images/emoji/apple/smile.png?v=15" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20"> .</p>
<p>I am not sure how to convey this properly however writing in some of the languages like Java is like driving a vehicle and in elixir is like playing on a guitar, completely different concepts even if there is common syntax in those programming languages.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="325934" 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/guard-clause-on-match-operator/62981/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-325934" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="325934"
                     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>