tbk

tbk

Reusing function variables in a `when` conditional

I have a function with a condition:

  def iteraterefs(divisor, number, table, out, i) when number >= divisor do
    number = number - divisor
    out = out <> elem(table, i)
  end

However it seems that the compiler does not like the condition when number >= divisor do, is there something about reuse of function variables I am missing from the documentation?

Marked As Solved

dimitarvp

dimitarvp

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.

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.

Also Liked

al2o3cr

al2o3cr

FunctionClauseError is what I’d expect from iteraterefs if it was called with number < divisor. You likely need to define it for those inputs as well to pass Exercism’s tests.

General note: this isn’t going to do what you want. i = i + 1 rebinds the name i inside the do / end block but that value doesn’t escape or even make it to the next iteration.

Same thing for out = out <> elem(table, i) inside iteraterefs; the name out is bound to a new name but then the scope ends immediately.

My recommendation would be to forget completely about Enum.each for a little while; it is almost never the right solution in Elixir.

tbk

tbk

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:

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 >= ref -> sym = elem(table, index)
                      iterate(num - ref, refs, table, index, out <> sym)
        true -> iterate(num, refs, table, index + 1, out)
      end
    end
  end 
end
benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Nicely done, a big improvement! Probably the only other change I’d advocate for is to do this:

  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 >= ref ->
        sym = elem(table, index)
        iterate(num - ref, refs, table, index, out <> sym)
      true ->
        iterate(num, refs, table, index + 1, out)
    end
  end

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!

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

We're in Beta

About us Mission Statement