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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dogweather" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dogweather/120/1906_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dogweather
                    <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="dimitarvp" data-post="21" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>Complement <code>@spec</code> with your own guards. If you know a datatype you use is actually a list, <strong>DO NOT</strong> guard it with <code>is_list(param)</code> . Define a guard and use that instead:</p>
</blockquote>
</aside>
<p>Very cool idea.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163247" 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/idiomatic-real-world-elixir-resources/28790/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-163247" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163247"
                     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="163279" data-post-id="163279">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve been writing typspecs in exported API functions in my work projects for the past 6 years, and I absolutely recommend this practice. When I started mentoring my current client’s team, typspecs were one of the first practice I introduced. They are currently mandatory, and we enforce them via credo.</p>
<p>I believe this is a good practice for improving code clarity. Imagine how it would look if Elixir or Erlang docs didn’t have typespecs. The same thing holds in our own code. I find it much easier to grasp and reason about a function when there are specs. In fact, in some cases, just looking at the specs can uncover some possible code design issue.</p>
<p>Since we write specs, we also use dialyzer during CI to detect possible problems. It’s far from perfect, but it’s better than nothing.</p>
<p>I’m not a fan of using guards in addition to specs. If an API function is accepting a list, I’ll use a typespec to indicate this, not a guard. Since Elixir is dynamic, and dialyzer can’t detect all problems, this means that the function might still end up accepting a non-list, in which case it’s behaviour is undefined. I’m mostly not worried about it though, b/c such issue can be prevented with good programming practices (like sanitizing the input at the edge of the system), and in my experience such situations are rare and they mostly occur in local dev, not in prod.</p>
<p>I quite like <a href="https://github.com/keathley/norm" rel="noopener nofollow ugc">norm</a>, but I’m currently not convinced that it’s a substitute for typespecs, because it’s a runtime check. It can complement specs though by helping us introduce tighter constraints at runtime. I still didn’t use it in practice but it’s definitely on my todo list.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163279" 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/idiomatic-real-world-elixir-resources/28790/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-163279" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163279"
                     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="163290" data-post-id="163290">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I have a lot to say on this topic in general, but I’ll restrict myself to a few points of agreement about specs, structs and compile time checks:</p>
<ul>
<li>Without specs the erlang and elixir docs would be far less useful. The primary benefit of specs is for documentation. Writing libraries without specs does your end users a disservice.</li>
<li>Dialyzer is extremely annoying and flawed, but it is the only practical mechanism we have to ensure that the specs we write match what our code is doing.</li>
<li>Structs take slightly more time to define than just using a map, but you get compile time guarantees that keys actually exist. I can refactor and change a key in one place and be sure that it gets updated everywhere else that references it.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163290" 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/idiomatic-real-world-elixir-resources/28790/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-163290" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163290"
                     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="163299" data-post-id="163299">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m not here to say whether or not you should use typespecs. If you like them, use them. But saying that authors who leave off typespeccs aren’t showing “idiomatic” or “real-world” elixir is factually incorrect and disingenuous. I realize you didn’t specifically say this <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a>, but that’s what’s others are implying in this thread.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="23" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I quite like <a href="https://github.com/keathley/norm" rel="noopener nofollow ugc">norm </a>, but I’m currently not convinced that it’s a substitute for typespecs, because it’s a runtime check. It can complement specs though by helping us introduce tighter constraints at runtime. I still didn’t use it in practice but it’s definitely on my todo list.</p>
</blockquote>
</aside>
<p>This is correct. Norm isn’t a <em>replacement</em> for typespecs. Norm is about specifying and validating interesting properties in your system, the majority of which can’t be expressed with a type system. If you want to use typespecs then Norm will provide a compliment to them and you’ll also get things like data generators and reasonable errors.</p>
<aside class="quote no-group" data-username="dimitarvp" data-post="19" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>What kind of growth are we talking about? If this is about rapid prototyping where you release 3 times a day then I’ll agree. But outside of that extreme case having stricter checks will definitely save you from mistakes made by tight schedules which will then tighten those schedules even further due to having to frantically fix bugs.</p>
</blockquote>
</aside>
<p>I was going to ignore this but I’m frustrated enough that I need to say something. Whenever I say that I want to continue to grow a system everyone assumes I mean, “move fast and break things” and the implication is that the people who value growth are careless, lack patience, and are otherwise thoughtless. I’m sick of this attitude. When I talk about growth I specifically mean growing a system <strong>without</strong> breakage. This design principle helps me and my team to continually deliver features <em>and</em> to build a system we can maintain over time. We do that by intentionally avoiding choices that will cause wide-spread breakages (such as <code>@enforce_keys</code>) and focus on building systems that are open to change. You’re (obviously) welcome to disagree with that mentality. The way we build systems may not be right for you and your team. But don’t for a moment assume that we make our design choices carelessly or because we just want to “build something quickly”.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163299" 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/idiomatic-real-world-elixir-resources/28790/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-163299" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163299"
                     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="163300" data-post-id="163300">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="keathley" data-post="25" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>saying that authors who leave off typespeccs aren’t showing “idiomatic” or “real-world” elixir is factually incorrect and disingenuous</p>
</blockquote>
</aside>
<p>Not sure if this was aimed at me, but just wanted to point out I didn’t say that. After all, my book doesn’t use specs too <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> I was considering having them, but ultimately didn’t go for it, because I estimated that the book is already packing quite a lot of information, and adding more stuff might confuse people and be counterproductive.</p>
<p>Perhaps that decision was wrong (though I didn’t hear  anyone complaining about it so far), but that was the line of thinking.  More generally, it’s to be expected that intro books leave out some of the things done in the “real world” to avoid hitting the readers with too much information at once. In my view, the value of a book is not just about what it teaches, but also about what it decides to leave out. Otherwise, we’d end up with a few thousand pages books which hardly anyone would be able to grasp within a reasonable amount of 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="163300" 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/idiomatic-real-world-elixir-resources/28790/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-163300" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163300"
                     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 #25"></div>
  </section>
</div>
    <div class="postbit" id="163301" data-post-id="163301">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sorry, that wasn’t a comment directed at you at all. I edited my post to try to clarify but by that point it was probably too late <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">.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163301" 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/idiomatic-real-world-elixir-resources/28790/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-163301" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163301"
                     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 #26"></div>
  </section>
</div>
    <div class="postbit" id="163305" data-post-id="163305">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="keathley" data-post="25" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>I’m not here to say whether or not you should use typespecs. If you like them, use them. But saying that authors who leave off typespeccs aren’t showing “idiomatic” or “real-world” elixir is factually incorrect and disingenuous.</p>
</blockquote>
</aside>
<p>There are two versions of “real-world” code, in my experience. One is applications (in the end product sense of the word) and the other is libraries/packages. I think that the vast majority of applications don’t use type specs, but most widely used libraries do.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163305" 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/idiomatic-real-world-elixir-resources/28790/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-163305" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163305"
                     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 #27"></div>
  </section>
</div>
    <div class="postbit" id="163308" data-post-id="163308">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sorentwo" data-post="28" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sorentwo/48/37360_2.png" class="avatar"> sorentwo:</div>
<blockquote>
<p>One is applications (in the end product sense of the word) and the other is libraries/packages.</p>
</blockquote>
</aside>
<p>Yes. I became a better Java programmer when I learned the distinction between the mindset of an author of a library/package vs. the author of an application.</p>
<p>The line can sometimes blur when you have part of an application serving as a library to other parts, but the overall point is a good one to raise. People accused of “over design” tend to be applying library concerns to applications. People accused of “irresponsible design” tend to apply application concerns to libraries.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163308" 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/idiomatic-real-world-elixir-resources/28790/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-163308" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163308"
                     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 #28"></div>
  </section>
</div>
    <div class="postbit" id="163315" data-post-id="163315">
  <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="keathley" data-post="25" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>Whenever I say that I want to continue to grow a system everyone assumes I mean, “move fast and break things” and the implication is that the people who value growth are careless, lack patience, and are otherwise thoughtless. I’m sick of this attitude.</p>
</blockquote>
</aside>
<p>Assumptions are a sad reality when people communicate only through text. Sorry that you got frustrated but no ill intent exists from my side.</p>
<p>It’s also very easy to assume that people are after rapid growth and this wasn’t aimed at you at all. It’s something that the business people do all the time and it’s something that I am personally sick of but it’s of course an uphill battle because they call all the shots and are free to pay 3 times for the same job because they didn’t listen the first time around. <img src="https://forum.elixirforum.com/uploads/default/original/2X/6/6c3193d1dd46244da3c8c6f719c9f5e2abdd5ae8.gif?v=15" title=":003:" class="emoji emoji-custom" alt=":003:" loading="lazy" width="20" height="20"> With time I started getting less angry about it.</p>
<aside class="quote no-group" data-username="keathley" data-post="25" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>When I talk about growth I specifically mean growing a system <strong>without</strong> breakage.</p>
</blockquote>
</aside>
<p>Same here. Unless we are on the same team and we actually have to make a good back-and-forth discussion to establish where the disconnect is coming from then we should do stuff like we feel is best for us. You won’t catch me trash-talking about it.</p>
<p>Mine was an honest question because I am not idolising any philosophy and I (hopefully) understand all techniques we can apply to our work have context and ideal conditions. Conversely, under other conditions they aren’t applicable at all (like insisting on having <code>@spec</code> everywhere during the initial project phases).</p>
<aside class="quote no-group" data-username="keathley" data-post="25" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>But don’t for a moment assume that we make our design choices carelessly or because we just want to “build something quickly”.</p>
</blockquote>
</aside>
<p>It’s an easy assumption to make because that’s the status quo at the 95% of everywhere I worked ever, and I am sorry if that felt like it was said with an ill will – it wasn’t.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163315" 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/idiomatic-real-world-elixir-resources/28790/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-163315" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163315"
                     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 #29"></div>
  </section>
</div>
    <div class="postbit" id="163321" data-post-id="163321">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sorentwo" data-post="28" data-topic="28790">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sorentwo/48/37360_2.png" class="avatar"> sorentwo:</div>
<blockquote>
<p>There are two versions of “real-world” code, in my experience. One is applications (in the end product sense of the word) and the other is libraries/packages. I think that the vast majority of applications don’t use type specs, but most widely used libraries do.</p>
</blockquote>
</aside>
<p>I agree with app vs library point, but I’m not sold on the conclusion. I don’t have enough of a sample to know what “the wast majority of applications” does, but in my limited experience of trying both approaches for a couple of years, I definitely prefer app code with specs, because they help me understand what are the allowed inputs and what are the possible outputs, which in turn reduces the uncertainty when reasoning about the code.</p>
<p>Consider for example the following function:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def create_account(params)
</code></pre>
<p>What is this function accepting and what is it returning? To know this we need to look into the implementation. If we’re lucky, the impl is simple and we see everything in that function’s body. But quite often, we have to dig through a bunch of other private functions to piece it all together. This is cumbersome, energy draining, and error prone.</p>
<p>Consider in contrast the spec version:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@type account_params :: %{
        first_name: String.t(),
        last_name: String.t(),
        email: String.t(),
        password: String.t(),
        role: Role.t()
      }

@spec create_account(account_params()) :: {:ok, Account.t()} | {:error, Ecto.Changeset.t()}
def create_account(params) do
</code></pre>
<p>This already tells us so much more without forcing us to read the entire implementation. That is in my view a key benefit of typespecs. Combined with proper naming and well defined responsibilities they provide great help in reasoning about the code, library or app.</p>
<p>This is why I prefer to say that types are first and foremost about documenting, not about catching bugs. When a type checker complains, it means that there is a discrepancy between the spec and the implementation. From the standpoint of the desired program behaviour we don’t know what is wrong (in fact the program might even be correct), but we do know that the documentation (spec) doesn’t match the code, so we need to fix something to sync them.</p>
<p>I agree though that one should not be fanatical. I typically spec only API functions (i.e. exported funs which are not marked with <code>@impl</code> or <code>@doc false</code>), except for modules such as Phoenix controllers or Graphql resolvers, because specs don’t really help here at all. I might occasionally spec a private function if I estimate that it’s interface is complex and the inclusion of specs will assist the reader.</p>
<p>When it comes to docs/moduledocs, I don’t write them in the app code unless there are some important implications not obvious from the name/spec combo.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="163321" data-batch-url="/posts/batch_likers">
                        10
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/idiomatic-real-world-elixir-resources/28790/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-163321" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="163321"
                     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 #30"></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/28790/load_more?page=4">Load more posts (1 remaining)</a>
</div></template></turbo-stream>