Enum.reduce/2 throws Enum.EmptyError

My choice would have been:

defmodule Demo do
  def run(a_list, default_value) do
    iterator = fn
      x, ^default_value -> x
      x, win when win < x -> x
      _, win -> win
    end
    Enum.reduce(a_list, default_value, iterator)
  end
end

IO.inspect (Demo.run [], :no_winner)
IO.inspect (Demo.run [1,2,3], :no_winner)
IO.inspect (Demo.run [3,1,2], :no_winner)
$ elixir demo.exs
:no_winner
3
3

Of course intercepting the empty case before it gets to the reduce is more “efficient” (though by all accounts pattern matching is pretty fast) and ultimately creates the scenario that reduce/2 was designed for - i.e. it already has been established that the enumerable has at least one item (which doesn’t need to be evaluated by the function).

defmodule Demo2 do
  def reduce([h|t],f) do
    Enum.reduce(t,h,f)
  end
end

fun = fn (x, acc) -> x * 2 + acc end
IO.inspect (Enum.reduce [3,2,1],0,fun)
IO.inspect (Demo2.reduce [3,2,1],fun)
IO.inspect (Enum.reduce [3,2,1],fun)
$ elixir demo2.exs
12
9
9