Deep nested update, struct/map and lists?

This comes so timely :slight_smile:

On thing I wonder, though.

I tested using (having imported Access)

[:notes, filter(&(&1.id == 1)), :sections, filter(&(&1.id == 2))]

instead of

[:notes, filter(&(&1.id == 1)), key(:sections), filter(&(&1.id == 2))]

But thatā€™s not working as expected. So the regular (non-function) key path elements donā€™t seem to combine with :get_and_update style functions. Is that true? You know why that is?

Is it the unzip part thatā€™s missing there?

To thow in another 3rd party library, my colleague wrote lens. A bit more extensive explanation can be found in this article.

The gist of the usage is:

  • A lens ā€œfocusesā€ desired elements (e.g. Lens.filter(&(&1.id == 123))).
  • Lenses are composable (e.g. Lens.key(:notes) |> Lens.filter(&(&1.id == 1)) |> Lens.key(:sections) |> Lens.filter(&(&1.id == 2)))
  • Lenses can work with Kernel.*_in (e.g. update_in(my_data, Lens.key(:notes) |> ..., &(&1 |> ...))
  • No special macro magic required (i.e. no use or import). Stock lenses in the Lens module are functions, and you can build your own lenses as function which chain them. There is a deflens macro which is a fairly simple convenience helper, but in many cases you donā€™t need to use that macro at all.

Weā€™ve been using lens for more than a year to transform and work on a deeply nested structure of polymorphic elements, and itā€™s been working well for us. If you plan on using it on a larger dataset, I advise to check the performance, because Iā€™m not sure that a lot of effort has been invested in that area.

2 Likes

The :section navigation reaches into your Notes struct which doesnā€™t implement the Access behaviour - therefore you need Access.key/2 to generate the navigation function for you.

The :notes navigation reaches into a standard Map which does implement the Access behaviour - so the necessary functionality already exists in the Map module.

1 Like

OK, now the picture emerges for me. Thanks so much!

That looks very interesting. Truly powerful.

Once the internal functions start looking lacking for a use-case, this seems a good small toolkit to take on as a dependency. Thanks so much.

1 Like