Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursion and anonymous functions in elixir

I'm trying to define an anonymous function to do a dot product, I can code this as a private function without any problem but I am struggling with the anonymous function syntax. I know I could implement this differently but I am trying to understand how to define anonymous functions with pattern matching and recursion. This is my current implementation

dot = fn
  [i|input],[w|weights], acc -> dot.(input,weights,i*w+acc)
  [],[bias],acc -> acc + bias
end

And I get this error on compile:

function dot/0 undefined

Any hints? Is this just not possible?

like image 368
Batou99 Avatar asked Feb 24 '14 08:02

Batou99


People also ask

How do you use recursion in anonymous functions?

Anonymous recursion primarily consists of calling "the current function", which results in direct recursion. Anonymous indirect recursion is possible, such as by calling "the caller (the previous function)", or, more rarely, by going further up the call stack, and this can be chained to produce mutual recursion.

How does anonymous function define elixir?

Anonymous Functions Just as the name implies, an anonymous function has no name. As we saw in the Enum lesson, these are frequently passed to other functions. To define an anonymous function in Elixir we need the fn and end keywords.

What is anonymous function with example?

An anonymous function is a function that was declared without any named identifier to refer to it. As such, an anonymous function is usually not accessible after its initial creation. Normal function definition: function hello() { alert('Hello world'); } hello();

What is the purpose of anonymous functions?

Anonymous functions, also known as closures , allow the creation of functions which have no specified name. They are most useful as the value of callable parameters, but they have many other uses. Anonymous functions are implemented using the Closure class.

How do I make a function anonymous in Elixir?

To define an anonymous function in Elixir we need the fn and end keywords. Within these we can define any number of parameters and function bodies separated by ->. Let’s look at a basic example: iex> sum = fn (a, b) -> a + b end iex> sum.(2, 3) 5

Why does elixir pattern match the arguments of a function?

The reason for this behavior is that Elixir pattern-matches the arguments that a function is called with against the arity the function is defined with. Let’s think about how the data looks when it arrives to Greeter1.hello/1:

How are guards tested in Elixir?

Once Elixir has matched a function any existing guards will be tested. In the following example we have two functions with the same signature, we rely on guards to determine which to use based on the argument’s type:

What is the use of anonymous function in C?

Anonymous functions have no name and are used to fulfil some functionality in the form of small code blocks. Generally, anonymous functions are the ultimate choice for small pieces of code or functions that have fewer calls. The building blocks of an anonymous function are fn, ->, and end.


3 Answers

It is not possible to recur on anonymous functions in Elixir.

Erlang 17 (currently a release candidate) adds this possibility to Erlang and we plan to leverage it soon. Right now, the best approach is to define a module function and pass it around:

def neural_bias([i|input],[w|weights], acc) do
  neural(input,weights,i*w+acc)
end

def neural_bias([], [bias], acc) do
  acc + bias
end

And then:

&neural_bias/3
like image 102
José Valim Avatar answered Oct 22 '22 16:10

José Valim


The less formal but still acceptable approach is:

factorial = fn
  (0,_) -> 1
  (1,_) -> 1
  (n, fun) -> n * fun.(n - 1, fun)
end

You call it with factorial.(6, factorial) # 720

like image 44
hamiltop Avatar answered Oct 22 '22 16:10

hamiltop


Here's a fixed (Y) combinator:

fix = fn f -> 
    (fn z ->
        z.(z)
    end).(fn x -> 
        f.(fn y -> (x.(x)).(y) end)
    end)
end

Here's how you use it:

factorial = fn factorial ->
    fn
        0 -> 0
        1 -> 1
        number -> number * factorial.(number - 1)
    end
end

fix.(factorial).(6) # 720

Only works with functions that recurse with 1 argument. Elixir doesn't have variable arguments. To support multiple arguments, you'll need to add more arguments than the single y like: f.(fn a,b -> (x.(x)).(a,b) end).

like image 13
CMCDragonkai Avatar answered Oct 22 '22 15:10

CMCDragonkai