0
votes

I am unable to figure out how this works. Here are example codes from Elixir docs, and my thought processes on how they work. Please let me know if there's something wrong.

# Code example from Elixir docs
users = [%{name: "john", age: 27}, %{name: "meg", age: 23}]
all = fn(:get, data, next) do
    Enum.map(data, next) 
end
get_in(users, [all, :age])
#=> [27, 23]
  1. users is matched to a list that contains two maps.
  2. all is matched to a function that takes :get, data, next as parameters and performs Enum.map(data, next).
  3. Kernal.get_in(users, [all, :age]) is called.
  4. Since one of the keys, all, is a function, it's invoked as all(:get, users, next).
  5. Enum.map iterates over each element of users and calls next on it, returning a list.
  6. Value of :age key of each user in the list is returned as a list.

These are my questions based on this analysis:

  1. What is this function next? It was never defined nor provided, but how come no error is reported?
  2. Is it correct to summarize that when get_in is called with a function (in this example, all) as a key, it returns the values of keys (in this example, :age) from the result of that function?
  3. If my guess in 2. is correct, then what happens when the result of that function is not a dictionary type and does not have key-value pairs? Does it raise error?
1

1 Answers

1
votes

There are two perfect sources to retrieve info from. The first is Elixir Docs, that state for Kernel#get_in/2:

Gets a value from a nested structure.

[...]

If a key is a function, the function will be invoked passing three arguments, the operation (:get), the data to be accessed, and a function to be invoked next.

The ultimate source would be Elixir source code, where we can see the exact implementation of Kernel#get_in/2 in our particular case.

That said, next here plays the role of acc, to pass get_in forth to the tail recursion until list’s tail is empty.

The question 2 is perfectly answered in the docs.

The answer to the question 3 would be: another Kernel#get_in/2 will be matched on the previous step and the recursion will start to unveil.