Smart way to do 1+1?

Sure, just not what I was looking for :wink:

This will add any two integers >= 0 by sleeping consecutive amounts of time given by the integers and timing the process. This lets us hand off the calculation to nature.

You can additionally specify a scale factor that determines how many milliseconds each integer unit represents. For instance, the number 5 with a scale of 100 means sleep for 500 milliseconds. The scale defaults to 10.

As the scale goes down, the time you wait for the computation to return is shorter but the answer you get has more error, because overhead and performance of the machine have a significant impact. You can increase the scale if you can wait longer for a more certain answer.

defmodule Heisen do
  @spec plus(non_neg_integer, non_neg_integer, pos_integer) :: non_neg_integer
  def plus(a, b, scale \\ 10)
      when is_integer(a) and a >= 0 and
           is_integer(b) and b >= 0 and
           is_integer(scale) and scale > 0 do
    with {time, :ok} <- :timer.tc(&sleep/2, [[a, b], scale]) do
      time |> div(scale) |> div(1000)
    end
  end

  @spec sleep([non_neg_integer], pos_integer) :: :ok
  defp sleep([t | tail], scale)
       when is_integer(t) and t >= 0 and is_integer(scale) and scale > 0 do
    :timer.sleep(scale * t)
    sleep(tail, scale)
  end

  defp sleep([], _), do: :ok
end

Usage examples:

iex> Heisen.plus(1, 1)
2
iex> Heisen.plus(1, 1, 1)
3
iex> Heisen.plus(1, 1, 1)
7
iex> Heisen.plus(1, 1, 1)
4
iex> Heisen.plus(1, 1, 1000)
2
iex> Heisen.plus(1, 1, 1000)
2
iex> Heisen.plus(1, 1, 1000)
2
7 Likes

Ah you found the only issue with adding numbers this way. :slight_smile:

2 Likes

Back with a new way to add 1 and 1 together.

Step 1: add lua to Erlang
Step 2: Luex.dostring(l, "return 1 + 1")
Step 3: profit?

3 Likes

lol can’t argue with that one.

1 Like

Elixir is functional, so do it functional way:

# Peano's successor lambda
s = fn n -> fn z -> fn s -> s.(n.(z).(s)) end end end
# Peano's zero in lambda calculus
z = fn z -> fn _s -> z end end

add = fn m, n -> m.(n).(s) end

one = s.(z)
two = add.(one, one)

two.(0).(& &1 + 1)
#=> 2

TBH I am amazed that no one posted that already.

In fact this notation allows us to define all possible natural numbers and all loops with finite amount of steps.

We can even define multiplication if needed, but that is left as an exercise for the reader.

2 Likes