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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tbk" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tbk
                    <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>Well, maybe I attempt both at once, but I can’t get away from that error.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def iteraterefs(number, refs, table, out, i) when number &gt; 0 do
    a = if number &gt;= elem(refs, i) do
      reducenumber(elem(refs, i), number, elem(table, i), out)
    end
    out = if elem(a,1) &gt; 0 do
      iteraterefs(elem(a, 0), refs, table, elem(a, 1), i + 1)
    end
    out
  end

  def reducenumber(divisor, number, symbol, out) when number &gt;= divisor do
    number = number - divisor
    out = out &lt;&gt; symbol
    {number, out}
  end
</code></pre>
<p>Still it returns a parsing error on <code>iteraterefs</code>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">** (ArgumentError) errors were found at the given arguments:

       * 2nd argument: not a tuple
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317225" 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/reusing-function-variables-in-a-when-conditional/61541/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-317225" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317225"
                     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="317228" data-post-id="317228">
  <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="tbk" data-post="12" data-topic="61541">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/t/50afbb/48.png" class="avatar"> tbk:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">    a = if number &gt;= elem(refs, i) do
      reducenumber(elem(refs, i), number, elem(table, i), out)
    end
</code></pre>
</blockquote>
</aside>
<p>The <code>a</code> will be <code>nil</code> if the condition is not satisfied. You should include an explicit <code>else</code> clause if that is not what you want.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317228" 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/reusing-function-variables-in-a-when-conditional/61541/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-317228" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317228"
                     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="317229" data-post-id="317229">
  <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’m not quite sure which line is doing that.  I was kind of blowing past some of your code and realize you have <code>out &lt;&gt; symbol</code>.  <s>Assuming <code>symbol</code> is a symbol, the <code>&lt;&gt;</code> operator only works on strings.</s> (oops sorry, that’s my old Ruby brain talking there)</p>
<p>Which line is it failing on?  It wouldn’t be <code>elem</code> because the 2nd argument of <code>elem</code> is an integer index.</p>
<p>Speaking of <code>elem</code>, I like to generally stay away from it in favour of pattern matching as it’s much clearer.</p>
<p>Instead of:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">tuple = {1, 2}
one = elem(tuple, 0)
two = elem(tuple, 1)
</code></pre>
<p>you can simply do:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">tuple = {1, 2}
{one, two} = tuple
</code></pre>
<p><code>elem</code> is basically just useful in pipelines (even then I personally don’t like to use 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="317229" 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/reusing-function-variables-in-a-when-conditional/61541/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-317229" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317229"
                     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="317232" data-post-id="317232">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tbk" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tbk
                    <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>It’s erroring on the function signature <code>def iteraterefs(number, refs, table, out, i) when number &gt; 0 do</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="317232" 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/reusing-function-variables-in-a-when-conditional/61541/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-317232" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317232"
                     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="317237" data-post-id="317237">
  <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">
								<p>IMO this thread is getting a bit too micro, you are kind of posting an error after error and I think you should step back and just post your entire module source code, and state the end goal.</p>
<p>It also sounds like you haven’t practiced Elixir enough if lack of mutability and the lexical scope are still surprising for you. Exercism requires some understanding of the language’s constructs. Without that you’ll just be crashing into one error after another, as it seems it is happening currently.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317237" 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/reusing-function-variables-in-a-when-conditional/61541/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-317237" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317237"
                     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>
    <div class="postbit" id="317612" data-post-id="317612">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tbk" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tbk
                    <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>I went away, far up into the mountains which are the Elixir documents, I learned many things and when I returned to take on the challenge again, it neatly folded before me like the recursion I used to solve it:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
  @refs {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @refs, @table, 0, "")
  end

  defp iterate(num, refs, table, index, out) do
    if num == 0 do 
      out
    else
      ref = elem(refs, index)
      cond do
        num &gt;= ref -&gt; sym = elem(table, index)
                      iterate(num - ref, refs, table, index, out &lt;&gt; sym)
        true -&gt; iterate(num, refs, table, index + 1, out)
      end
    end
  end 
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317612" 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/reusing-function-variables-in-a-when-conditional/61541/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-317612" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317612"
                     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="317614" data-post-id="317614">
  <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">
								<p>Nicely done, a big improvement! Probably the only other change I’d advocate for is to do this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  defp iterate(0, _refs, _table, _index, out) do
    out
  end

  defp iterate(num, refs, table, index, out) do
    ref = elem(refs, index)
    cond do
      num &gt;= ref -&gt;
        sym = elem(table, index)
        iterate(num - ref, refs, table, index, out &lt;&gt; sym)
      true -&gt;
        iterate(num, refs, table, index + 1, out)
    end
  end
</code></pre>
<p>It’s conventional that when you’re doing recursion like this to define the “base case” or “termination case” as its own clause up front, and then you have other clauses after. This is entirely a stylistic thing though, so it’s up to you!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317614" 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/reusing-function-variables-in-a-when-conditional/61541/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-317614" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317614"
                     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="317625" data-post-id="317625">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Looks reasonable, though using lists can help avoid tricky off-by-one or off-the-end issues with <code>elem</code>.</p>
<p>As a demonstration of that principle, here are some refactors of the module:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table {{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}}

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, 0, "")
  end

  defp iterate(num, table, index, out) do
    if num == 0 do 
      out
    else
      {sym, ref} = elem(table, index)
      cond do
        num &gt;= ref -&gt;
          iterate(num - ref, table, index, out &lt;&gt; sym)

        true -&gt;
          iterate(num, table, index + 1, out)
      end
    end
  end
end
</code></pre>
<p>This first refactor keeps the tuple-shaped <code>table</code>, but brings the symbols and the values together for readability and future maintainability. Having <code>@table</code> and <code>@refs</code> be different-sized tuples would be Not Good, so combining them together makes that bug <em>impossible</em>.</p>
<p>There’s another place for bugs to hide, though: when we write <code>iterate(num, table, index+1, out)</code>, that will try to execute <code>elem(table, index+1)</code> and give:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">** (ArgumentError) errors were found at the given arguments:

  * 1st argument: out of range

    :erlang.element(14, {{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}})
    iex:21: RomanNumerals.iterate/4
</code></pre>
<p>(this happened in an earlier version when I made a typo)</p>
<p>The root cause is that the recursive call to <code>iterate</code> assumes that a “next” element of <code>table</code> exists, without checking. You <em>could</em> add extra checks to ensure that <code>index &lt; tuple_size(table)</code>, but again it’s better to write code that literally <em>can’t</em> run off the end.</p>
<p>First, a very bad refactor that makes things slower. <code>Enum.at</code> is expensive compared to <code>elem</code>, since it needs to traverse the list. This also applies the early-exit cleanup that <a class="mention" href="/u/benwilson512" rel="nofollow">@benwilson512</a> suggested.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, 0, "")
  end

  defp iterate(0, _, _, out), do: out

  defp iterate(num, table, index, out) do
    {sym, ref} = Enum.at(table, index)
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, index, out &lt;&gt; sym)

      true -&gt;
        iterate(num, table, index + 1, out)
    end
  end
end
</code></pre>
<p>This will fail in a slightly different way for an negative input (match error vs argument error) but it still “goes off the end” and crashes. Checking <code>length(table)</code> is expensive (traversing the list again!) so checking is even harder. Why am I telling you to use lists anyways?</p>
<p>Two things come together to make lists powerful here:</p>
<ul>
<li>
<p>a call to <code>iterate</code> will only ever care about  <code>index</code> or higher in <code>table</code></p>
</li>
<li>
<p>There’s one place in a list that <em>isn’t</em> expensive to access: the first element (aka “the head”). It’s also easy to check for, since only <code>[]</code> doesn’t have a head.</p>
</li>
</ul>
<p>This refactor applies that principle: instead of keeping track of <code>table</code> and <code>index</code> separately, it uses <code>hd</code> and <code>tl</code> to interact with the first element and the rest. This is fast and requires no allocations.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, "")
  end

  defp iterate(0, _, out), do: out

  defp iterate(num, table, out) do
    {sym, ref} = hd(table)
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, out &lt;&gt; sym)

      true -&gt;
        iterate(num, tl(table), out)
    end
  end
end
</code></pre>
<p>A small cleanup refactor: the pattern of “do something with <code>hd</code> and something else with <code>tl</code>” is so common that it’s usually not written explicitly. This uses pattern-matching to accomplish the same thing as the previous version</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, "")
  end

  defp iterate(0, _, out), do: out

  defp iterate(num, [head | rest] = table, out) do
    {sym, ref} = head
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, out &lt;&gt; sym)

      true -&gt;
        iterate(num, rest, out)
    end
  end
end
</code></pre>
<p>It’s also very common to absorb a binding like <code>{sym, ref} = head</code> into the function head:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, "")
  end

  defp iterate(0, _, out), do: out

  defp iterate(num, [{sym, ref} | rest] = table, out) do
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, out &lt;&gt; sym)

      true -&gt;
        iterate(num, rest, out)
    end
  end
end
</code></pre>
<p>This version crashes in yet a different way, so what can we do about it? The error message gives us a clue:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(26)&gt; RomanNumerals.numeral(-1)                                                                                                                                       
** (FunctionClauseError) no function clause matching in RomanNumerals.iterate/3    
    
    The following arguments were given to RomanNumerals.iterate/3:
    
        # 1
        -1
    
        # 2
        []
    
        # 3 
        ""
    
    iex:36: RomanNumerals.iterate/3
</code></pre>
<p>Think about what <code>iterate</code> being called with <code>[]</code> for <code>table</code> means: the conversion process has run out of symbols to try. That’s directly representable in code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, "")
  end

  defp iterate(0, _, out), do: out
  defp iterate(_, [], _), do: raise("bad number")

  defp iterate(num, [{sym, ref} | rest] = table, out) do
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, out &lt;&gt; sym)

      true -&gt;
        iterate(num, rest, out)
    end
  end
end
</code></pre>
<p>Another not-actually-relevant-here-but-worth-keeping-in-mind tip on performance: <code>&lt;&gt;</code> in a loop (or recursion) should be regarded with suspicion as it can result in lots of short-lived binaries. A common idiom avoids the repeated operations and does them at the end:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, [])
  end

  defp iterate(0, _, out), do: out |&gt; Enum.reverse() |&gt; Enum.join()
  defp iterate(_, [], _), do: raise("bad number")

  defp iterate(num, [{sym, ref} | rest] = table, out) do
    cond do
      num &gt;= ref -&gt;
        iterate(num - ref, table, [sym | out])

      true -&gt;
        iterate(num, rest, out)
    end
  end
end
</code></pre>
<p>As a final cleanup, the <code>cond</code> with one non-default branch could be replaced with an <code>if</code> - or even a guard! The guard style makes the control structures disappear almost completely:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RomanNumerals do
  @doc """
  Convert the number to a roman number.
  """
  @table [{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}]

  @spec numeral(pos_integer) :: String.t()
  def numeral(number) do
    iterate(number, @table, [])
  end

  defp iterate(0, _, out), do: out |&gt; Enum.reverse() |&gt; Enum.join()
  defp iterate(_, [], _), do: raise("bad number")

  defp iterate(num, [{sym, ref} | _] = table, out) when num &gt;= ref do
    iterate(num - ref, table, [sym | out])
  end

  defp iterate(num, [_ | rest], out) do
    iterate(num, rest, out)
  end
end
</code></pre>
<hr>
<p>Apologies for the long post, but I wanted to avoid the usual “the steps between these two versions are OBVIOUS” hand-waving and justify each piece.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317625" 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/reusing-function-variables-in-a-when-conditional/61541/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-317625" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317625"
                     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="317898" data-post-id="317898">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tbk" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tbk
                    <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>There is a lot of really good learning in this post. I had been using List splitting in function signatures but had not thought to further disambiguate those elements using a set. The information on Enum and hd/tl was new as was placing wildcards in a signature. The idea of building a list and joining at the end seems to have a lot of value.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="317898" 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/reusing-function-variables-in-a-when-conditional/61541/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-317898" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="317898"
                     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>