3

I am learning Elixir and I am working on Project Euler to try to strengthen my skills in Elixir. Right now I have this code

fib = fn a,b,0 -> a a,b,n -> fib.(b, a+b, n-1) end IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> fib.(0,1,n) end), even and fn(x) -> x < 4000000 end)) 

But when I run this code I get:

undefined function fib/0 (elixir) src/elixir_fn.erl:33: anonymous fn/3 in :elixir_fn.expand/3 (stdlib) lists.erl:1238: :lists.map/2 (stdlib) lists.erl:1238: :lists.map/2 (elixir) src/elixir_fn.erl:36: :elixir_fn.expand/3 

How do I fix this?

1 Answer 1

7

Elixir does not allow defining anonymous recursive functions at this moment. You have 2 options: define a normal function using def inside any module, or use the following trick (hack?) to make kind of anonymous recursive functions:

fib = fn fib, a, b, 0 -> a fib, a, b, n -> fib.(fib, b, a+b, n-1) end IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> fib.(fib, 0, 1, n) end), fn(x) -> rem(x, 2) == 0 && x < 4000000 end)) 

I would recommend defining this function in a module instead of using this hack:

defmodule Fib do def fib(a, _b, 0), do: a def fib(a, b, n), do: fib(b, a + b, n - 1) end IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> Fib.fib(0, 1, n) end), fn(x) -> rem(x, 2) == 0 && x < 4000000 end)) 

Note: there was also a syntax error in the second argument to Enum.filter/2 which I've fixed (hopefully correctly).

Tip: please read about the pipe operator to make the IO.puts code more idiomatic: http://elixir-lang.org/getting-started/enumerables-and-streams.html#the-pipe-operator

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much! Sorry I'm incredibly new to elixir so I'm still trying to get a feel for the language.
No need to be sorry. I'm sure your code would work in many languages (it does in JS) and it's reasonable to expect this to work in Elixir. In fact, you can define anonymous recursive functions in Erlang since OTP 17 but Elixir doesn't have an equivalent feature implemented yet.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.