Qqwy
Hello everyone,
I wrote a small library today called MapDiff.
It returns a map listing the (smallest amount of) changes to get from map_a to map_b:
iex> foo = %{a: 1, b: 2, c: %{d: 3, e: 4, f: 5}}
iex> bar = %{a: 1, b: 42, c: %{d: %{something_else: "entirely"}, f: 10}}
iex> MapDiff.diff(foo, bar)
%{changed: :map_change,
value: %{a: %{changed: :equal, value: 1},
b: %{added: 42, changed: :primitive_change, removed: 2},
c: %{changed: :map_change,
value: %{d: %{added: %{something_else: "entirely"},
changed: :primitive_change, removed: 3},
e: %{changed: :removed, value: 4},
f: %{added: 10, changed: :primitive_change, removed: 5}}}}}
This is mainly useful if you have two maps describing the state of something, where
replacing all of the old state and then filling in the new is too slow, which means that only
replacing the things that actually are changed is better.
It is similar to what Elm does to represent its output to the HTML Domain Object Model. The reason I wrote MapDiff is that I am planning on writing a library that wraps Erlang’s wxWidgets bindings in a similar way that Elm wraps the HTML DOM, which would allow people to write GUIs in a Functional style (wxWidgets itself is Object-Oriented). Does this sound like a huge undertaking? Yes! Let’s see how far I can get with it
…
Anyhow, MapDiff is a very small and basic library, but it might be useful for some other people as well, so I thought I’d publish it on Hex.pm
. Feedback is of course greatly appreciated.
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 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
sashaafm
That seems like a useful simple library! Good job @Qqwy!
OvermindDL1
That would be awesome and is entirely possible! I’d thought about it myself but wrapping to a QT layer instead. ^.^
This library will be useful to me though, I already have my more specialized one currently.
Qqwy
Hey @OvermindDL1! Please do tell me more about your ‘more specialized one’. And also, I’m of course going to try to keep the Functional Reactive Programming layer as separate as possible from the WxWidgets layer, so hopefully it will be possible to swap one rendering backend for another.
But this is all still completely theoretical right now, of course
.
OvermindDL1
Mine just converted atoms to binaries if it compared an atom and binary, just an ease of use thing and I can always convert it before of course. ^.^
Qqwy
All right! MapDiff is updated to
1.1.0.The single but important new feature: Supporting structs in a meaningful way.
Examples:
When comparing two different kinds of structs, this of course results in a
:primitive_change, as they are simply considered primitive data types:Qqwy
By the way,
The library consists of one small module (or actually, one single public function, even).
The code still uses quite a few
if/elsestatements inside this function definition. Is there a way to make this code even more Elixir-idiomatic?bbense
Short circuit the equal case maybe ?
iex(1)> foo = %{ :a => 1, :b => 2 }
%{a: 1, b: 2}
iex(2)> bar = %{ :a => 1, :b => 2 }
%{a: 1, b: 2}
iex(3)> foo == bar
true
bbense
Another way to go would be to create a Diff protocol and recursive apply the protocol in it’s implementation.
andre1sk
It’s possible to do same things with functions and pattern matches something like
https://github.com/andre1sk/elixir_map_diff/blob/refactor/lib/map_diff.ex
Qqwy
The equal case is already short-cirquiting, see line 139.
I thought about this, but decided against it, as I believe that the current implementation is the only one that makes sense (different types of structs → primitive change, same types of structs → recurse over struct keys).
This is absolutely amazing. I had no idea that it was possible to refactor it so beautifully
. Please do open Pull Request, so I can put these changes in and give you credit!