tcoopman
Help me refactor chained map updates
Let’s say I have some code like this
defmodule Foo do
def foo do
state = %{state | a: a(state)}
state = %{state | b: b(state)}
state = %{state | c: c(state)}
state
end
def a(s)…
def b(s)…
def c(s)…
end
is there a cleaner way to do that?
Trending in Questions
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated!
To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead.
Sta...
New
Hello !
We want new/edit form pages to POST/PUT to their own URL rather than the resources REST defaults (post /things, put /things/:id)...
New
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app?
Looking for hints regarding:
Addi...
New
Hi all, I wanted to ask how the community is dealing with post-release steps.
Today we have Ecto migrations, which make sure that the db...
New
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New
Other Trending Topics
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
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
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











First 10 of 20 Posts!
garrison
If the functions themselves updated the state you could pipe them.
I do this a lot in GenServers.
tcoopman
Yeah that’s definitely an option. But I need to refactor quite a bit for that because the functions are used in other places as well that don’t need the full state. So I was first looking at some other options.
windexoriginal
Take a look at Map.update!/3.
garrison
Yeah, it’s contextual. I still do what you’ve done sometimes as well.
Zurga
You could reduce
garrison
Note that this is actually slightly different because in the OP the entire state is the input to the function.
mudasobwa
I see kinda XY Problem here to begin with. Functions retrieving the partial state from the full state could be either trivial wrappers for destructuring (
def a(%{a: value}), do: value) or in-place calculations of some additional values based on the whole state. From your comments, I understood we are dealing with the latter.That said, you potentially have inconsistencies in the state (when a bare
a(state)gets called without updating the state.) The arguably best property of Erlang/Elixir (of the actor model in general) is its proven responsibility to keep the state consistent no matter what. That basically suggests to calculate changes on update, store them within the state, and retrieve them with a baredotnotation.I understand that the refactor involving changes in many places is something you want to avoid, but I’d better refactor the state to keep the value you are to retrieve later and amend it in the single place in the way which does not depend on the call order (your example does,) and does not use readers.
adamu
Let me check the requirements: You want to update a map repetedly, specifying the key, and a function that has the same name as the key, where each function accepts the full state and returns the new value for the corresponding key. Each update should use the latest version of the state.
You could wrap this behaviour in a function:
Then call it like this:
You could even go further an make a macro that ensures the key and function name are the same, but that’s probably making things more confusing rather than simpler.
tcoopman
Thanks for all the ideas.
In the end I went ahead and refactored the code and make each function have a
state → statesignature. This cleans things up quite a bit.I’m still thinking about the code though because the correctness obviously relies on the order of execution of the functions and that is quite implicit in the current implementation. I don’t have good solutions for that. So while it works it feels a bit brittle. But that’s probably my bias
adamu
Just for fun:
Then:
I’m not sure if
unquote(__MODULE__).unquote(fun)(unquote(state))is the best way to call a function in the same module when the function name is specified by an atom…Last Post!
Zurga
State might have changed in a way after
a(state)that affects the outcome fromb(state)