# Recursion Issue

**URL:** <https://forum.elixirforum.com/t/recursion-issue/33518>\
**Category:** Discussions\
**Tags:** book-programming-elixir, learning-elixir, elixir-ls\
**Created:** [August 3, 2020, 10:21am UTC](https://forum.elixirforum.com/t/recursion-issue/33518 "2020-08-03T10:21:55Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![owaisqayum](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/owaisqayum/32/20018_2.png) [@owaisqayum](https://forum.elixirforum.com/u/owaisqayum)\
**Post date:** [August 3, 2020, 10:21am UTC](https://forum.elixirforum.com/t/recursion-issue/33518/1 "2020-08-03T10:21:55Z")

</div>

Hi,

I am attempting to solve a problem in Exercism “Protein Translation” and implemented the following code. I want the split(tail, final\_list) to recursively add the 3 char to final\_list. What am I doing wrong and how can I improve the code.

```elixir
defmodule PT do

  def rna(string) do
    split(string, [])
  end

  def split(string, final_list) when string == "", do: final_list

  def split(string, final_list) do
    splitting = String.split_at(string, 3)
    [head | tail] = Tuple.to_list(splitting)

    final_list ++ [head]
    split(tail, final_list)
  end
end

```

i am getting this error:

```elixir
iex(21)> PT.rna("Owaissdui")
** (FunctionClauseError) no function clause matching in String.Unicode.next_grapheme_size/1    
    
    The following arguments were given to String.Unicode.next_grapheme_size/1:
    
        # 1
        ["issdui"]
    
    Attempted function clauses (showing 10 out of 19263):
    
        def next_grapheme_size(<<13::integer(), 10::integer(), rest::binary()>>)
        def next_grapheme_size(<<"\r"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"\n"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇰"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇱"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇲"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇳"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇴"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇵"::binary(), rest::binary()>>)
        def next_grapheme_size(<<"󠇶"::binary(), rest::binary()>>)
        ...
        (19253 clauses not shown)

```

Thanks

---

<div class="post-metadata">

**Author:** ![Dusty](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dusty/32/23609_2.png) [@Dusty](https://forum.elixirforum.com/u/Dusty)\
**Post date:** [August 3, 2020, 10:49am UTC](https://forum.elixirforum.com/t/recursion-issue/33518/2 "2020-08-03T10:49:06Z")

</div>

One issue that jumps out right away is that you are not binding the expression:

```elixir
final_list ++ [head]

```

to any variable (in order to capture the new value).

---

<div class="post-metadata">

**Author:** ![kokolegorille](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kokolegorille/32/4784_2.png) [@kokolegorille](https://forum.elixirforum.com/u/kokolegorille)\
**Post date:** [August 3, 2020, 10:50am UTC](https://forum.elixirforum.com/t/recursion-issue/33518/3 "2020-08-03T10:50:11Z")

</div>

> [@owaisqayum](#):
>
> ```elixir
> def split(string, final_list) when string == "", do: final_list
> 
> ```

You might simplify with

```elixir
def split("", final_list), do: final_list

```

> [@owaisqayum](#):
>
> ```elixir
> final_list ++ [head]
> split(tail, final_list)
> 
> ```

We live in an immutable world 🙂

final\_list is not changing…

---

<div class="post-metadata">

**Author:** ![srowley](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/srowley/32/28720_2.png) [@srowley](https://forum.elixirforum.com/u/srowley)\
**Post date:** [August 3, 2020, 11:07am UTC](https://forum.elixirforum.com/t/recursion-issue/33518/4 "2020-08-03T11:07:55Z")

</div>

You are getting the error because `tail` is a list, but you are passing it to `split/2` which expects the first argument to be a string. `split/2` takes `tail` and tries to call `String.split/2`, which then throws an error because it expects its first argument to be a string, not a list.

If you simply want to split a string into lists of three characters, I can think of ways that are simpler, but using this approach I would suggest:

```elixir
  def split("", final_list), do: Enum.reverse(final_list)

  def split(string, final_list) do
    {first_three_characters, rest_of_word} = String.split_at(string, 3)
    split(rest_of_word, [first_three_characters | final_list])
  end

```

---

<div class="post-metadata">

**Author:** ![owaisqayum](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/owaisqayum/32/20018_2.png) [@owaisqayum](https://forum.elixirforum.com/u/owaisqayum)\
**Post date:** [August 3, 2020, 2:07pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/5 "2020-08-03T14:07:53Z")

</div>

You are right, but here am just appending the head to final list right or am doing something wrong ?

---

<div class="post-metadata">

**Author:** ![owaisqayum](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/owaisqayum/32/20018_2.png) [@owaisqayum](https://forum.elixirforum.com/u/owaisqayum)\
**Post date:** [August 3, 2020, 2:09pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/6 "2020-08-03T14:09:11Z")

</div>

Wont it just return the value as we that in elixir the last expression of a function gets returned automatically. I might be wrong, can you kindly advice ?

---

<div class="post-metadata">

**Author:** ![owaisqayum](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/owaisqayum/32/20018_2.png) [@owaisqayum](https://forum.elixirforum.com/u/owaisqayum)\
**Post date:** [August 3, 2020, 2:21pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/7 "2020-08-03T14:21:27Z")

</div>

you are absolutely right and it’s such a dumb mistake to make. A very solid way of using pattern matching. One question, why you have used a tuple and why not a list

```elixir
    {first_three_characters, rest_of_word} = String.split_at(string, 3)

```

Is it because we have fixed arguments or is there any other reason as well?

Also, in this case

```elixir
[first_three_characters | final_list]

```

it’s concatenating a string with a list, how it actually works?

---

<div class="post-metadata">

**Author:** ![srowley](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/srowley/32/28720_2.png) [@srowley](https://forum.elixirforum.com/u/srowley)\
**Post date:** [August 3, 2020, 3:02pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/8 "2020-08-03T15:02:03Z")

</div>

`String.split/2` returns a tuple, so only a tuple will match on the result returned by that function.

I am prepending the string to an accumulated list of strings. This is a common practice as prepending to a list is more efficient than appending to one. That is also why `Enum.reverse/1` is called at the end, because prepending ends up generating a list of items in reverse that needs to be reversed again to preserve the original order.

---

<div class="post-metadata">

**Author:** ![owaisqayum](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/owaisqayum/32/20018_2.png) [@owaisqayum](https://forum.elixirforum.com/u/owaisqayum)\
**Post date:** [August 3, 2020, 3:06pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/9 "2020-08-03T15:06:37Z")

</div>

Thank you for such a detailed response.

---

<div class="post-metadata">

**Author:** ![mpope](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@mpope](https://forum.elixirforum.com/u/mpope)\
**Post date:** [August 3, 2020, 10:04pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/10 "2020-08-03T22:04:42Z")

</div>

> [@owaisqayum](#):
>
> `final_list ++ [head]`

I think reading [this section in the docs](https://erlang.org/doc/efficiency_guide/myths.html#myth--operator--++--is-always-bad) on the ‘left hand copy’ of the `++` operator could clarify why prepending is faster, for future reference.

---

<div class="post-metadata">

**Author:** ![Dusty](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dusty/32/23609_2.png) [@Dusty](https://forum.elixirforum.com/u/Dusty)\
**Post date:** [August 3, 2020, 11:24pm UTC](https://forum.elixirforum.com/t/recursion-issue/33518/11 "2020-08-03T23:24:39Z")

</div>

In this case, the last expression in your function is

```elixir
split(tail, final_list)

```

which calls `split/2` using the same value for `final_list` that was passed to the function originally. You have already discussed that `tail` is causing a type error in this case, but regardless, the result of your list concatenation operation is simply thrown away.
