mudasobwa
The library to easily map/each/reduce/map_reduce/filter deeply nested maps/keywords/lists, called Iteraptor has been released. Besides standard map-reduce operations, it allows flattening nested terms and deflattening them back, and provides a couple of helper methods for low-level traversing them.
There is a blog post describing the interface in details, and Hexdock.
We were using it in production for months, but since we were not able to catch more bugs on our limited set of nested structures, I would be glad to hear about other use-cases where it fails to traverse the nesteds properly.
Also, it’s extremely handy when one needs to filter out some deeply nested keys, or get just the second level of a nested map, or produce a flattened keyword list out of external config file ![]()
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Qqwy
This kind of functionality seems like the perfect fit for Property-based testing
gon782
Indeed, that was my immediate thought as well.
@mudasobwa what is the reasoning behind the names of some of the operations? I would expect
eachto never return anything, for example, as well as formapto preserve the structure of the thing it’s mapping over. These are standard behaviors connected with the terminology in FP as far as I know and I assume most people familiar with it would expect the same.mudasobwa
I am not sure what did you mean by “
mapto preserve the structure of the thing it’s mapping over”—mine does to the extent it is able to.For
eachwe cannot return literally nothing, due to implicit returns in Elixir; the standardEnum.each/2returns:okbut I found it more convenient to return the input as is (making it easy to inject into|>pipes asIO.inspecte.g. does.mudasobwa
Thanks for the suggestion, I’ll do. I am pretty sure though that there is no perfect testing environment where all the issues might be covered, that’s why I kindly asked for bug reports, if any.
gon782
I mean exactly what I wrote. It’s expected that a
mappreserves the structure/shape/form of what it’s mapping over. You go against that expectation in your examples, hence my comment about your naming being somewhat odd.Same goes for
each. There is no nothing on the BEAM, so I wouldn’t expect you to return that, but to expect actual output fromeachis to go against expectation. If someone uses youreachas a last expression in a function they won’t get what they were expecting.I think your library seems good and it’s certainly something that has a use, but your names are not idiomatic. I don’t know if these are Ruby-isms, but I’d argue that you should either change the behavior or the names somewhat to match idiomatic FP.
mudasobwa
I never went against that. neither did the code. There is a misunderstanding because this is AFAICT the first implementation of nested term mapping. You have likely mentioned this example:
Please note, that it’s a bare map having the only element in a nutshell. You should not be fooled by the fact that the first value is also a map. So, by what is expected—my
mapfunction should return a 1-sized map. That’s it. It does.Even more, by default (without an explicit option
yield: allpassed,) the only leaves will be passed to mapper and what you originally expected would happen out of the box (mapper will be called only once with[:a, :b, :c], {:c, 42}as arguments.)Sometimes, though, one wants to map deeply nested whatever (but not the leaf) to something else. And this library provides such a possibility by accepting
yield: alloption. This is an extended mode when the library consumer is allowed to map anything on any nesting level. The consistency on each level is still preserved:Enumerableof sizeNwill be mapped toEnumerableof sizeN.To make it clear with the aforementioned example:
Is it looking more familiar now? Well, IMHO yes, because we mapped
foowhatever it is to something new. I hope I made the intent/implementation clearer.Regarding
eachI plain disagree, sorry for saying that. Since you said “return nothing” in the first place, I treat it as “the caller must not rely on what it returns.” There is no contract on whateachshould return. And I return the structure itself for easier piping (Erlang does not have pipe operator, that’s why it makes not much sense to return anything butokatom from erlang mappers, but Elixir indeed does.) I don’t see any violation of expectations here.gon782
Naming is about social contracts and both of these functions (and a host of other ones) are associated with certain behaviors in all languages. None of what you’ve explained about your additional behavior changes that. To each his own, though.
mudasobwa
Iteraptorgets a new feature inv1.10.1:Iteraptor.jsonify/2to deeply convert all theKeywordlists toMaps.Jasonas well as some other json encoding libraries have issues with marshalling keyword lists, because internal representation ofKeywordis eventually a list of tuples, and tuples are not encodeable.Iteraptor.jsonify/2traverses the deeply nested term and recursively converts all the keywords to maps.