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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>before the fix:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">##### With input 30 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int      318.01 K        3.14 μs   ±771.75%           3 μs           5 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int         4.26 KB

**All measurements for memory usage were the same**

##### With input 6 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int      903.01 K        1.11 μs  ±3457.31%           1 μs           2 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int           592 B

**All measurements for memory usage were the same**

##### With input 606 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int       43.65 K       22.91 μs    ±73.77%          22 μs          44 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int         3.73 KB
</code></pre>
<p>with the fix:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">##### With input 30 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int      316.97 K        3.15 μs   ±659.73%           3 μs           5 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int         4.26 KB

**All measurements for memory usage were the same**

##### With input 6 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int      930.26 K        1.07 μs  ±3092.95%           1 μs           2 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int           592 B

**All measurements for memory usage were the same**

##### With input 606 Digits Integer #####
Name                           ips        average  deviation         median         99th %
Decimal.add()    Int       43.93 K       22.77 μs    ±29.74%          22 μs          39 μs

Memory usage statistics:

Name                    Memory usage
Decimal.add()    Int         3.73 KB
</code></pre>
<p>As you can see the cost in this case is not relevant. <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" 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="180031" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-180031" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180031"
                     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="180039" data-post-id="180039">
  <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="razuf" data-post="13" data-topic="32430">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/48/19266_2.png" class="avatar"> razuf:</div>
<blockquote>
<p>As you can see the cost in this case is not relevant. <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>I think the largest cost here isn’t in performance, or even in the code required for this specific PR, but in what this implies about coding strategy. The principle you’re articulating is that <em>every</em> public function on a public API should validate the invariants of the datastructure. I don’t think this is a sound principle. It happens to be reasonably cheap in this case, but that is by no means guaranteed. It also puts a massive burden on library authors.</p>
<p>If you aren’t trying to articulate a general principle, then the question becomes, why enforce these checks here and not elsewhere?</p>
<p>The right pattern is to enforce invariants at the point of documented constructors.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180039" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-180039" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180039"
                     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="180042" data-post-id="180042">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes, thank you very much. Theoretically perfect formulated!</p>
<aside class="quote no-group" data-username="benwilson512" data-post="14" data-topic="32430">
<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>The right pattern is to enforce invariants at the point of documented constructors.</p>
</blockquote>
</aside>
<p>But thats the point.</p>
<p>Theoretically we can use Decimal.new as this kind of single entry point and close all other - but thats in the practical case of the current architecture of this Decimal lib not possible - it’s used a lot in other projects (money, ecto, …)- of course change radical everything - maybe possible … I wrote a small side project (for fun) the lib Apa - Arbitrary Precision Artithmetic  with a different architecture (tuple vs. struct / integers and strings vs lists)… but thats not the case here … I want to help to make the original Decimal lib more safe! <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" 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="180042" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-180042" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180042"
                     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="180043" data-post-id="180043">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="razuf" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/120/19266_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  razuf
                    <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="benwilson512" data-post="14" data-topic="32430">
<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>The principle you’re articulating is that <em>every</em> public function on a public API should validate the invariants of the datastructure</p>
</blockquote>
</aside>
<p>by the way … it already does it a lot:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def add(%Decimal{coef: :inf}, %Decimal{coef: :inf}),
    do: error(:invalid_operation, "adding +Infinity and -Infinity", %Decimal{coef: :NaN})
</code></pre>
<p><img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji only-emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>But really I appreciate this discussion - thanks a lot!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180043" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-180043" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180043"
                     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="180045" data-post-id="180045">
  <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="razuf" data-post="15" data-topic="32430">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/48/19266_2.png" class="avatar"> razuf:</div>
<blockquote>
<p>but thats in the practical case of the current architecture of this Decimal lib not possible</p>
</blockquote>
</aside>
<p>Can you clarify why this isn’t possible? The money and Ecto apps should always use either 1) use the safe constructors or 2) take complete responsibility for using the structs wrong.</p>
<aside class="quote no-group" data-username="razuf" data-post="16" data-topic="32430">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/48/19266_2.png" class="avatar"> razuf:</div>
<blockquote>
<p>by the way … it already does it a lot:</p>
</blockquote>
</aside>
<p>Those aren’t protections against intentionally broken data structures, that’s traditional app logic. You can generate infinite numbers via the safe public API, and in that case the add function handles it. You’re proposing a more extensive model where the safeguards need to handle not just the domain of valid decimals but the domain of all nonsense decimals too.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180045" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-180045" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180045"
                     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="180048" data-post-id="180048">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Again - theoretically you are absolute right - we could discuss if 0 or NaN or Inf are nonsense too … but no hairsplitting … <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>I like your really correct thinking. And if we find both a way for a new solution - wonderful!</p>
<p>What would you suggest?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180048" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-180048" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180048"
                     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="180049" data-post-id="180049">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>If I would be radical - as you suggested - I would remove the struct</p>
<p>%Decimal{sign: sign, coef: coef, exp: exp}</p>
<p>and use tuples of arbitrary integers:<br>
{integer(), integer()}<br>
{-12, -3} == -0.012</p>
<p>no limits no restrictions, all possible math numbers are constructible</p>
<p>and an add function for example like this:<br>
<a class="mention" href="/u/spec" rel="nofollow">@spec</a> add({integer(), integer()}, {integer(), integer()}) ::{integer(), integer()}</p>
<p>composable, piping (of course) and nice performance… <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>with well defined entry points …</p>
<p>… but it’s sounds like a dream … I would break a lot of old stuff <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" 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="180049" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-180049" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180049"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="180079" data-post-id="180079">
  <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="razuf" data-post="19" data-topic="32430">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/48/19266_2.png" class="avatar"> razuf:</div>
<blockquote>
<p>and use tuples of arbitrary integers:</p>
</blockquote>
</aside>
<p>How does this make any difference? An end user can construct hostile tuples in the same way that they can construct hostile or nonsense decimals.</p>
<aside class="quote no-group" data-username="razuf" data-post="18" data-topic="32430">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/razuf/48/19266_2.png" class="avatar"> razuf:</div>
<blockquote>
<p>we could discuss if 0 or NaN or Inf are nonsense too</p>
</blockquote>
</aside>
<p>But they aren’t, they’re a well defined value, you just can’t do all the operations to them, constructible via the public constructors.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180079" 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/decimal-bug-please-be-careful-with-negative-coefficients-fix-is-on-pull-request/32430/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-180079" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180079"
                     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>