sadjow

sadjow

How the put_in/2 works?

Reading the guides at this point http://elixir-lang.org/getting-started/keywords-and-maps.html#nested-data-structures We have an example that we can modify a specific data in a map using the put_in/2.

I’m curious how Elixir makes this work:

iex> users = [
  john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]},
  mary: %{name: "Mary", age: 29, languages: ["Elixir", "F#", "Clojure"]}
]
[john: %{age: 27, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},
 mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}]

iex> users = put_in users[:john].age, 31
[john: %{age: 31, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},
 mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}]

How Elixir returns the whole map? If we do not pass it to the function?

Thanks in advance.

Marked As Solved

jmitchell

jmitchell

put_in/2 is a macro, not a function. The arguments are passed unevaluated, and the put_in/2 implementation operates on their syntactic representations instead. Since the first argument is users[:john].age, the macro actually does have access to users.

Also Liked

NobbZ

NobbZ

Well, put_in/2 is not a function but a macro, so it can do any magic it wants with the AST of your first parameter before expanding itself.

You can find the definiton on github: elixir/lib/elixir/lib/kernel.ex at main · elixir-lang/elixir · GitHub

jmitchell

jmitchell

A good place to start is the Quote and unquote guide, and then the following section on macros. You may also find it helpful to study how the short-circuiting or AST macro works before trying to tackle put_in/2. In particular, notice that the right side is only evaluated when the left side is falsy, whereas if || were a function all of its arguments would be evaluated before the function body.

iex(1)> IO.puts "left" || IO.puts "right"
left
:ok
iex(2)> false || IO.puts "right"
right
:ok
sadjow

sadjow

Thanks @jmitchell and @NobbZ ! Awesome. I’ll read more about the macros to understand how it works!

Where Next?

Popular in Questions Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
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
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
New
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
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement