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.

Reply via email to