Sure it works but neither “looks” nor “feels” Can I streamline it somehow so that I don’t repeat gin = all the time?
I guess I could change each line into an anonymous function and pipe the outputs through but that would make this code block even larger I presume. Any better ways?
To be a little bit more concrete, say the requirement is to set key :a to 1 unless already set, and multiply key :b by 2 if set and otherwise set it to 2.
The piped variant looks very nice (the other is basically what I do now) but – I am sorry – I should have explained that the conditions/actions can also be more complex than simple “add if not present”, “add or update” . For example most ugly are things like “if x is set to a_value then set y to another_value and remove z”. While setting y and removing z can be done in separate steps - how does one reference the piped-in map so that checking one key and setting another (or checking one and removing another) could be done in one go. I see this possibility only with inline anon functions but maybe I am missing something here?
A common way to reference the piped map is by using then/2 but when I reach that point I tend to break up the pipe into multiple expressions and/or functions as I find following the logic that way easier.
I would just go one step further: don’t use anonymous functions, promote them to normal functions. This also gives you the advantage of having a pipe chain that’s more or less self-documenting.
Yes, that’s what I have in mind now too. I didn’t like the idea initially because those functions are not going to be “generic” enough for my taste. ATM this seems like the best option though. Thank you for confirming this.
Hmm, do you want to handle the case of a missing key differently from when an existing key’s value is nil or false? I generally prefer using the is_nil/1 and is_map_key/2 guards to make that distinction explicit in helper functions.
By the way, if you’re just concerned with missing keys, you might not even need conditional if statements. Map.put_new/3 already passes the map through unchanged when the key already exists while Map.update/4 accepts a default value when the key is missing.