I want to second this, the value of pipe-ready functions is an obvious one to me, it has so many downstream bonuses. If we improve this by one step or many I don't care, as I think naturally this will be kept in mind anyways for future functions.
On Fri, May 19, 2023 at 6:46 AM Christian Trosclair < christian.troscl...@dockyard.com> wrote: > > For me, I run into this often enough, that I wish this was a thing. > Clearly, YMMV. > > Strictly speaking, yes. But I think just updating the *_lazy versions is > sufficient for the level of consistency already present. I mean, there's no > Map.put_lazy when there clearly could be and I don't think not changing > update makes things worse. (sorry for the double negatives there) > The documentation for a revised Map.update would need to be careful. > There' would be a lot going on to explain. > On Friday, May 19, 2023 at 7:54:46 AM UTC-4 woj...@wojtekmach.pl wrote: > >> I believe an apples-to-apples comparison would be: >> >> # before >> x >> |> then(&Map.put_new_lazy(&1, :file_path, fn -> >> Path.join([&1.base_path, &1.filename]) end)) >> >> # after >> x >> |> Map.put_new_lazy(:file_path, &Path.join([&1.base_path, >> &1.filename])) >> >> And I think it does read better. >> >> That being said, personally I don’t think I have commonly needed >> something like this though and I’d just break out of a pipe and move on. :) >> If we add this precedent, that the function receives the input as one of >> the arguments, should we update other functions for consistency too? Do we >> have an Map.update accepting a 2-arity function? (Is the map the first or >> the second argument?!) >> >> On 19 May 2023, at 13:30, Christian Trosclair <christian...@dockyard.com> >> wrote: >> >> It is sometimes if not often desirable to build up some Map or Keyword >> list and add or update values in such a way that takes into account the >> current state of the data, yet some of the current functions do not allow >> this to be done from a pipe. >> >> A trivial example for instance: >> ``` >> map = %{filename: “thing.txt”} >> map = Map.put_new(map, :base_path, "/") >> map = Map.put_new(map, :file_path, Path.join([map.base_path, >> map.filename])) >> >> ``` >> This is begging to be piped, but Map.put_new_lazy/3’s function argument >> does not receive the current map. >> >> For reference Map.put_new_lazy/3 >> >> https://github.com/elixir-lang/elixir/blob/a64d42f5d3cb6c32752af9d3312897e8cd5bb7ec/lib/elixir/lib/map.ex#L381 >> >> It is true we could simply use Kernel.then/2, but I think we can do >> better and make code easier to scan. >> >> An example using pipes and Kernel.then/2 >> ``` >> %{filename: “thing.txt”} >> |> Map.put_new(:base_path, "/") >> |> then(&(Map.put_new(&1, :file_path, Path.join([&1.base_path, >> &1.filename])))) >> >> ``` >> Kernel.then/2 is breaking up what could be a quick scan of the code. >> >> We can smooth this out. >> >> Here is an implementation on Map.put_new_lazy/3 >> >> ``` >> @spec put_new_lazy(map, key, ((map) -> value)) :: map >> def put_new_lazy(map, key, fun) when is_function(fun, 1) do >> case map do >> %{^key => _value} -> >> map >> >> %{} -> >> put(map, key, fun.(map)) >> >> other -> >> :erlang.error({:badmap, other}) >> end >> end >> >> ``` >> Then we could rewrite the original example like: >> >> ``` >> %{filename: “thing.txt”} >> |> Map.put_new(:base_path, "/") >> |> Map.put_new_lazy(:file_path, &(Path.join([&1.base_path, >> &1.filename])))) >> >> ``` >> If we wanted to go even further, we could even accept an arity 2 function >> and pass in both the map and the key. >> >> Thoughts? >> >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-lang-co...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/bc728f96-ff11-40c1-b90f-b412e241fbd9n%40googlegroups.com >> <https://groups.google.com/d/msgid/elixir-lang-core/bc728f96-ff11-40c1-b90f-b412e241fbd9n%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/2ea1ed78-45eb-4299-8bfe-2a5f96984709n%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/2ea1ed78-45eb-4299-8bfe-2a5f96984709n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- Kurtis Rainbolt-Greene, Software Developer & Founder of Difference Engineers 202-643-2263 -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAMhJPGg3LeNr8zi_5iS%3Dujex1KTSXufQAh8O29vY1Er5ZGaUPA%40mail.gmail.com.