cevado

cevado

nm - a tool to work with deeply nested data structures

I’ve just publish something I’ve been experimenting with:

Since the discussion about local accumulators I’ve joined some discussions on ways to deal with it properly.
I’ve always argued that this is difficult and yes, it should be difficult, you’re trying to change a deeply nested tree of data and you’re trying to apply mutability adhoc to a immutable data structure. Thinking on ways to handle that more easily I’ve always come to the conclusion that the “simple”(not the best and not the fastest) is just to unnest that tree into a more “linear” structure. That’s where the starting point for nm.

So nm is a erlang library because there is no need to anything special to elixir. It has some limitations, it only consider “nesteable data structures” as lists and maps, so keywordlists, tuples and other data types will not be “unnested”.
This is very early work, i’ve just come with the most simple and basic api that can be useful and somewhat easy to use. I’ve been thinking to improve that api with something close to the Access behavior, but first I gonna improve documentation and provide some examples(I’m planning to do an example in elixir and erlang for doing the problem that Valim shows in the local accumulators repository).

I’d like to receive some feedback and opinions on this type of library if it makes sense and all that. If you could just apply it to your most nasty deeply nested structures and see if it’s useful, i’d be thankful. :slight_smile:

First Post!

cevado

cevado

someone drew my attention that on hex there is no link to the repository.
Also I made this example using the library for the problem statement that Valim did in the local accumators thread.

defmodule Traversal do
  def traverse(data) do
    {:ok, t} = :nm.unnest(data)
    {:ok, root} = :nm.get_value(t, :root)
    Enum.reduce(root, {t, 1, 1}, &root_traversal/2)

    :nm.nest(t)
  end

  defp root_traversal({:"$nm_ref", id}, {t, c1, c2}) do
    {:ok, current} = :nm.get_value(t, id)
    {:"$nm_ref", list_id} = current["lessons"]
    {:ok, list} = :nm.get_value(t, list_id)

    updated = Map.put(current, "position", c1)
    :nm.fast_update(t, id, updated)

    c2 = if current["reset_lesson_position"], do: 1, else: c2
    {_, c2} = Enum.reduce(list, {t, c2}, &lessons_traversal/2)
    {t, c1 + 1, c2}
  end

  defp lessons_traversal({:"$nm_ref", id}, {t, c}) do
    {:ok, current} = :nm.get_value(t, id)
    updated = Map.put(current, "position", c)
    :nm.fast_update(t, id, updated)

    {t, c + 1}
  end
end

Where Next?

Popular in Libraries Top

blatyo
https://www.conduitframework.com/ The best overview for how things are tied together is this presentation. Modules and functions are pre...
New
mhanberg
I just released the first version of Temple: an HTML DSL for Elixir and Phoenix! You can read this blog post or the docs for more info...
New
hpopp
After just over two years in development, this latest version of Pigeon is what I finally consider done in regards to my original vision ...
New
praveenperera
FastRSS Parse RSS feeds very quickly: This is rust NIF built using rustler Uses the RSS rust crate to do the actual RSS parsing Speed...
New
kevinlang
Hey all, We have made an Ecto3 Adapter for SQLite3, ecto_sqlite3! We have successfully on-boarded the full suite of integration tests (...
New
asiniy
Hey there! I wrote a download elixir package which does exactly what its name about - an easy way to download files. I saw solutions ...
New
mbuhot
Leverage Open Api 3.0 (Swagger) to document, test, validate and explore your Plug and Phoenix APIs. Generate and serve a JSON Open API ...
New
josevalim
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below. Hi everyone, We a...
New
Crowdhailer
I have been updating a library that allows you to pipe between functions that use the erlang result tuple convention. Assuming you have...
New
New

Other popular topics Top

josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
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
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Sub Categories:

We're in Beta

About us Mission Statement