# String to integer tuple API

**URL:** <https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253>\
**Category:** Questions\
**Tags:** strings, parsing, integer\
**Created:** [July 26, 2019, 10:23am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253 "2019-07-26T10:23:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fl4m3Ph03n1x](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/32/11709_2.png) [@Fl4m3Ph03n1x](https://forum.elixirforum.com/u/Fl4m3Ph03n1x)\
**Post date:** [July 26, 2019, 10:23am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/1 "2019-07-26T10:23:34Z")

</div>

## Background

I want to convert a String to an integer. To this extent I know I can use one of the two following functions:

1. `String.to_integer`
2. `Integer.parse`

## My concern

My concern here is the API. With option 1 if the string is invalid, it will just raise an exception and explode. This is not very _elixiry_ as it forces me down to a `try/rescue` approach.

So the alternative would be option 2. Except the API for this function is rather inconsistent. Sometimes it will return `:error` other times it will just explode. Quite literally, I do not know what to expect, so I still need to use a `try/rescue` here as well.

## Question

My objective is to have a parsing function that returns a tagged tuple for the errors. Something among the lines of `{:error, reason}`. Now, I know I can easily create one, but I was wondering if there is a function in Elixir that already does this.

Is there any parse function in Elixir that already returns tagged tupples when parsing data?

---

<div class="post-metadata">

**Author:** ![jola](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jola/32/18010_2.png) [@jola](https://forum.elixirforum.com/u/jola)\
**Post date:** [July 26, 2019, 10:31am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/2 "2019-07-26T10:31:39Z")

</div>

For 1. I disagree with you, I consider it perfectly elixiry. The function is for data that you _know_ can be parsed as an integer. You should not use it for unknown inputs. The documentation is pretty clear

> `string` must be the string representation of an integer. Otherwise, an [`ArgumentError`](https://hexdocs.pm/elixir/ArgumentError.html) will be raised. If you want to parse a string that may contain an ill-formatted integer, use [`Integer.parse/1`](https://hexdocs.pm/elixir/Integer.html#parse/1).

What makes `Integer.parse` explode? It should give you either a tuple of number and remainder or `:error`.

Ah, I see it raises if you give it an invalid base, not because you give it an invalid string input.

---

<div class="post-metadata">

**Author:** ![NobbZ](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nobbz/32/27235_2.png) [@NobbZ](https://forum.elixirforum.com/u/NobbZ)\
**Post date:** [July 26, 2019, 10:33am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/3 "2019-07-26T10:33:47Z")

</div>

If there can be at least one digit be parsed to the given base, you’ll get `{integer, rest}`, `:error` otherwise, rasie should only happen if the `base` is invalid.

```elixir
case Integer.parse(str) do
  {num, ""} -> {:ok, num}
  {_, rest} -> {:error, :unparsable}
  :error -> {:error, :unparsable}
end

```

---

<div class="post-metadata">

**Author:** ![Fl4m3Ph03n1x](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/32/11709_2.png) [@Fl4m3Ph03n1x](https://forum.elixirforum.com/u/Fl4m3Ph03n1x)\
**Post date:** [July 26, 2019, 11:02am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/4 "2019-07-26T11:02:47Z")

</div>

> [@jola](#):
>
> For 1. I disagree with you, I consider it perfectly elixiry.

I respect your opinion, but I would like to direct you to the official Elixir documentation, in specific to this part:

> In Elixir, we avoid using `try/rescue` because **we don’t use errors for control flow**. We take errors literally: they are reserved for unexpected and/or exceptional situations.

Source: [https://elixir-lang.org/getting-started/try-catch-and-rescue.html#errors](https://elixir-lang.org/getting-started/try-catch-and-rescue.html#errors)

> [@NobbZ](#):
>
> , rasie should only happen if the `base` is invalid.

I am aware of this. My objective here is to find out if there is a parsing function in Elixir that doesn’t throw and always returns a tagged tupple. I understand this is not the case, correct?

---

<div class="post-metadata">

**Author:** ![NobbZ](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nobbz/32/27235_2.png) [@NobbZ](https://forum.elixirforum.com/u/NobbZ)\
**Post date:** [July 26, 2019, 11:03am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/5 "2019-07-26T11:03:48Z")

</div>

There is none, but you can easily wrap yourself, as I have shown in my code example.

---

<div class="post-metadata">

**Author:** ![jola](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jola/32/18010_2.png) [@jola](https://forum.elixirforum.com/u/jola)\
**Post date:** [July 26, 2019, 11:35am UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/6 "2019-07-26T11:35:38Z")

</div>

I believe you’re misunderstanding the intent of that paragraph. It is correct that errors are not used as control flow, and that’s why the function explicitly says “must be the string representation of an integer”. The paragraph supports this, you shouldn’t wrap `String.to_integer` in a `try`. That’s the intent of the paragraph, not that errors are not used at all. Rather they should be used for “unexpected and/or exceptional situations”, such as someone passing `"hello"` to `String.to_integer`. Just like it should raise if it is passed `:potato`.

Elixir consistently raises `ArgumentError` for invalid inputs in the cases where the input doesn’t make sense at all.

Another great example of this is of course `Integer.parse`, which accepts any string, because it’s made specifically for unknown string inputs, while it throws an `ArgumentError` if the `base` is incorrect.

Digging deeper into the Elixir source can be helpful here, where you’ll find lots of instances of raising `ArgumentError` (there are also other errors used regularly, like `KeyError`)

> **[Build software better, together](https://github.com/search?q=repo%3Aelixir-lang%2Felixir+raise+ArgumentError)**
>
> GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.

---

<div class="post-metadata">

**Author:** ![hauleth](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/32/18942_2.png) [@hauleth](https://forum.elixirforum.com/u/hauleth)\
**Post date:** [July 26, 2019, 12:01pm UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/7 "2019-07-26T12:01:08Z")

</div>

Will you really allow user to specify base? Or you will really use base over 36? In general almost all Elixir functions can throw when passed incorrect arguments. Do you also want to prevent situation when someone passes atom to `Enum.reverse/1`?

---

<div class="post-metadata">

**Author:** ![Ted](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ted/32/15126_2.png) [@Ted](https://forum.elixirforum.com/u/Ted)\
**Post date:** [July 26, 2019, 10:11pm UTC](https://forum.elixirforum.com/t/string-to-integer-tuple-api/24253/8 "2019-07-26T22:11:47Z")

</div>

I have a related question.

(Well, I _think_ it might be related; I’m a novice and everything’s possible. 😄 )

I see that Elixir’s naming conventions discuss [the trailing-bang](https://github.com/elixir-lang/elixir/blob/master/lib/elixir/pages/Naming%20Conventions.md#trailing-bang-foo):

> A trailing bang (exclamation mark) signifies a function or macro where failure cases raise an exception.
> 
> Many functions come in pairs, such as `File.read/1` and `File.read!/1` . `File.read/1` will return a success or failure tuple, whereas `File.read!/1` will return a plain value or else raise an exception…

So, in a parallel Elixir universe, could `Integer.parse` not exist and instead we’d have both `String.to_integer` and `String.to_integer!`?

**EDIT** : hmm, maybe that parallel universe would actually be a pain; I overlooked the fact that `Integer.parse` accounts for `remainder_of_binary` and `String.to_integer` doesn’t.
