softshipper
softshipper

Reputation: 34061

What does question mark mean?

Consider following module

defmodule Parse do

  def number([ ?- | tail ]), do: _number_digits(tail, 0) * -1
  def number([ ?+ | tail ]), do: _number_digits(tail, 0)
  def number(str),           do: _number_digits(str, 0)

  defp _number_digits([], value), do: value
  defp _number_digits([ digit | tail ], value) when digit in '0123456789' do
    _number_digits(tail, value*10 + digit - ?0)
  end
  defp _number_digits([ non_digit | _ ], _) do
    raise "Invalid digit '#{[non_digit]}'"
  end

end

When I import the file into shell and execute following statement:

iex(3)> Parse.number('123')

as output I've got

123

What I really do not understand is this line:

value*10 + digit - ?0

What does ?0 really mean? I know, when I write ?x on shell, it shows me the code point like

iex(13)> ?5
53
iex(14)> ?t
116

The ?0 has code point -48. The example above with 123, the calculation with first iteration number 1 would looks like(value*10 + digit - ?0):

0 * 10 + 1 - 48 

When I calculate by myself, I would get as result -47 but I've got 1, why?

Upvotes: 3

Views: 1681

Answers (1)

tom
tom

Reputation: 19153

? followed by a character gives you that character's Unicode code point value.

The - ?0 done in the second clause of the _number_digits function subtracts the code point of the character '0' from the digit's code point value. This conveniently gives you the integer 0 for the digit '0', 1 for the digit '1', etc.

Thus, the entire value*10 + digit - ?0 expression first multiples the running total (value) by 10 (since we're dealing with base-10 input strings), then adds the value for the current digit under consideration. This happens recursively until all digits of the input string are consumed, given you the integer represented by the input string.

Upvotes: 14

Related Questions