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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Erlang-Core-Team" data-username="garazdawi" data-post="11" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/garazdawi/48/5853_2.png" class="avatar"> garazdawi:</div>
<blockquote>
<p>The documentation never states what <code>tid()</code> is, so you cannot assume in your code what it is.</p>
</blockquote>
</aside>
<p>Alright so what can I do with a <code>tid()</code> then?<br>
Are there any special uses for <code>tid()</code>s I am not aware of besides checking it’s a value != from <code>:undefined</code>?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127915" 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-test-breaks-the-opacity-of-its-argument/22307/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-127915" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127915"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="127916" data-post-id="127916">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="10" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>Which sounds completely … well… let’s say <em>unreasonable</em> .</p>
</blockquote>
</aside>
<p>It’s <em>unreasonable</em> when viewed with a static typing mindset. To some degree that is what <a href="https://blog.cleancoder.com/uncle-bob/2017/01/11/TheDarkPath.html" rel="noopener nofollow ugc">The Dark Path</a> is about.</p>
<p>It doesn’t mean static typing is evil but if the type system isn’t up to snuff static typing can lead to unnecessary coupling.</p>
<hr>
<p>Then again it’s no different than being handed an instance reference in OO. The internal structure of the instance is unknown to the client - only the instance methods need to know what the internal structure of the instance is.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127916" 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-test-breaks-the-opacity-of-its-argument/22307/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-127916" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127916"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="12" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>Alright so what can I do with a <code>tid()</code> then?</p>
</blockquote>
</aside>
<p>You can pass it to any function in <code>ets</code> that takes a <code>tid()</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127918" 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-test-breaks-the-opacity-of-its-argument/22307/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-127918" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127918"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>… and the <code>:ets</code> module will know which table you are talking about.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127919" 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-test-breaks-the-opacity-of-its-argument/22307/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-127919" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127919"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="peerreynders" data-post="13" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>It’s <em>unreasonable</em> when viewed with a static typing mindset. To some degree that is what <a href="https://blog.cleancoder.com/uncle-bob/2017/01/11/TheDarkPath.html" rel="nofollow">The Dark Path</a> is about.</p>
</blockquote>
</aside>
<p>I don’t think this is a static vs dynamic typing thing. Statically typed languages wrap built in types in new types all the time which effectively creates opaque types.</p>
<p><a class="mention" href="/u/fl4m3ph03n1x" rel="nofollow">@Fl4m3Ph03n1x</a> The return value of the api is <code>tid()</code>. You can use it for any function that takes a <code>tid()</code>. Opaqueness just means that you shouldn’t look deeper into it to try to figure out what a <code>tid()</code> is composed of because <code>tid()</code> doesn’t make any promises about that.</p>
<p>It’s a little like a <code>MapSet</code>. <code>MapSet.new([1,2,3])</code> returns a <code>MapSet.t</code> and you can pass it to functions that accept that type. You shouldn’t try to do break apart the MapSet and grab the internal map out of it to try to mess with. That might change.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127921" 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/guard-test-breaks-the-opacity-of-its-argument/22307/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-127921" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127921"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="127924" data-post-id="127924">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="benwilson512" data-post="16" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/48/1457_2.png" class="avatar"> benwilson512:</div>
<blockquote>
<p>I don’t think this is a static vs dynamic typing thing. Statically typed languages wrap built in types in new types all the time which effectively creates opaque types.</p>
</blockquote>
</aside>
<p>It depends on the situation. In Java a custom class can wrap anything but with <a href="https://docs.oracle.com/javase/9/docs/api/javax/xml/ws/Holder.html" rel="noopener nofollow ugc">generics</a> details leak all the time leading to coupling - sometimes necessary, other times not so much. In some circumstances this leads to overuse of strings to avoid types.</p>
<p>In languages like Haskell and OCaml there are ways to keep that coupling under control - if you know what you are doing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127924" 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-test-breaks-the-opacity-of-its-argument/22307/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-127924" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127924"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="benwilson512" data-post="16" data-topic="22307">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/48/1457_2.png" class="avatar"> benwilson512:</div>
<blockquote>
<p>I don’t think this is a static vs dynamic typing thing. Statically typed languages wrap built in types in new types all the time which effectively creates opaque types.</p>
</blockquote>
</aside>
<p>Yeah, opaque types in OCaml and C++ are super common.  Like in OCaml the <code>*.ml</code> file:</p>
<pre data-code-wrap="ocaml"><code class="lang-ocaml">type t = string
</code></pre>
<p>And the <code>*.mli</code> file:</p>
<pre data-code-wrap="ocaml"><code class="lang-ocaml">type t
</code></pre>
<p>So inside the ml file they know it is a string, outside the file it is opaque and any other module that gets it can only store it around or pass it into some function that accepts it, but doesn’t know that it is a string nor can do anything with it that is not exposed from the original module.</p>
<p>Opaque types are a super static type thing, not a dynamic type thing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127944" 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-test-breaks-the-opacity-of-its-argument/22307/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-127944" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127944"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="127957" data-post-id="127957">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The point of opaque types is that the module, which defines the type has functions, which know how to handle the data. In the case of ets the <code>:ets</code> module knows what the data behind <code>tid()</code> is and what to do with it. <code>new</code> does return it, while lots of other functions use it. It does not matter if the current implementation of <code>tid</code> is an integer or a reference, as any code which is not inside of <code>:ets</code> is just supposed to hold on to the value, but not look at what’s inside. This allows <code>:ets</code> to refactor what <code>tid()</code> actually is without breaking client code.</p>
<p>Another example of an opaque type is <code>MapSet.t</code>. Behind the scenes mapsets are implemented using a map. But a map alone cannot guarantee the uniqueness required for sets. Therefore the datatype needs to be opaque so that (in a perfect world) nobody ever directly manipulates the data, but people need to use functions on the <code>MapSet</code> module for manipulation. The module can then guarantee that the constraints of a set datatype are adhered to.</p>
<p>Like mentioned for <code>:ets</code> the implementation for <code>MapSet</code> did already change over the livetime of elixir as well.</p>
<p>There are also tradeoffs to be made when using opaque types:</p>
<p>Only the single module defining the opaque type can actually do something with the data it holds. So the module needs to have functions for everything a client might want to do with said data. No other module can enhance or alter the behaviour around it without breaking the type contract.</p>
<p>Another caveat for opaque types is that you need to be careful with longterm storage of such types. If the runtime updates, but the stored value doesn’t it can result in failures.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="127957" 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/guard-test-breaks-the-opacity-of-its-argument/22307/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-127957" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="127957"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-solved cat-solved" title="Marked as solution"></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>