baxterw3b

baxterw3b

Anonymous functions with multiple body

Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with multiple body.

Basically if i have a function like this

handle_result = fn
{:ok, result} → IO.puts “handling the result…”
{:error} → IO.puts “an error is occurred”
end

and then

some_result = 1
handle_result.({:ok, some_result})

“handling the result…”

to me is ok, i pass a tuple and if match i return the string.

The point is that to me is like i’m using a switch statement, or a sort of case statement, and if the value that i pass match a case, i print the string, so what’s the difference to use a function like this or
use a switch in other languages? and another thing is, how can i use multiple bodies to compare if two values are equal or not equal with operators like && == || using multiple bodies? cause everytime i try it cause me errors.

last thing that i don’t get is, the argument of the function is implicit? because usually if i do

fn a,b →
a == b
end

is clear, i pass two values and then i compare a to b, but i don’t get it this thing of multiple bodies with the tuples and pattern matching.

sorry guys, but i’m a lot confuse. :slight_smile:

thanks.

Most Liked

tyro

tyro

The point is that to me is like i’m using a switch statement, or a sort of case statement, and if the value that i pass match a case, i print the string, so what’s the difference to use a function like this or
use a switch in other languages?

Function clauses perform the control flow of switch statements (i.e. they allow branching on conditions) but they also bind values to variables at the same time. e.g. In the second line of:

handle_result = fn
  {:ok, result} -> IO.puts "handling the result..."
  {:error} -> IO.puts "an error is occurred"
end

a condition is checked (is the argument of the form {:ok, result}?), AND, if the condition is true, a value is bound to the variable ‘result’. A switch case does not assign values to variables but pattern matching does.

how can i use multiple bodies to compare if two values are equal or not equal with operators

You can use ‘when’ to add conditions to clauses:

fn 
  a,b when a > b -> ...
  a,b when a < b -> ...
  a,b -> 
end

last thing that i don’t get is, the argument of the function is implicit?

Not exactly. The arguments are pattern matched with each function clause. So for your example

fn a,b -> #  This is equivalent to fn a = arg1, b = arg2 ->
  a == b
end
Qqwy

Qqwy

TypeCheck Core Team

Let me try to answer your questions:

Using multiple function heads is ‘sort of’ the same thing as a switch-case, but more powerful.
In languages like C and C++, you are only allowed to use int-like values in a switch case, as these can be optimized by the compiler to a direct jump at best, or a binary search at worst. Therefore, things like strings are not allowed.

In most imperative or object-oriented interpreted languages, however, this optimization does not happen. You are allowed to use any value in a switch statement, but this is treated as just syntactic sugar for an if ()... else if () ... else if ()...-chain.

In languages like Elixir that support pattern-matching, however, the case statement is a lot more powerful than a plain 'ol switch: The compiler will recognize what properties you are trying to ascertain of your data types, and underwater write the appropriate checks that only check what needs to be checked; redundant checks are not performed.
While this is of course marginally less fast than the ‘direct jump’ approach that C/C++ support, it is a lot faster than a simple if... else if-chain. And on the other hand, it makes for extremely readable code.

The compiler will take function with multiple heads (it does not matter if it is a named or anonymous function, it works the same way), and rewrite these multiple heads using a case-statement underwater. So yes, in this way, they are doing the same thing.

But from a code organization perspective, it usually is better to separate your functionality in many small named functions, because it makes it easier in the future to change only a small part.

In the case that a pattern is matched in a function head or in a case statement, only the variables that are part of that statement are available (also available are the ones before the function or case statement, but notably not the ones named in the other functin heads / case matches).

EDIT: @tyro was a little bit faster than me :smiley: , but I hope you still find my background explanation helpful or at least entertaining :stuck_out_tongue_winking_eye: .

baxterw3b

baxterw3b

Thank you guys! Now i understand everything! And Thank you for Your time

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement