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?
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.
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.
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();
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.
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
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:
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:
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.
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
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
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)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With