`maybe` is a common prefix for functions that may or may not do something, 
eg:

https://github.com/elixir-lang/elixir/blob/779ccdb7564d587dfdadc1285a4dc57eb24768a1/lib/logger/lib/logger.ex#L1074

https://github.com/elixir-lang/elixir/blob/779ccdb7564d587dfdadc1285a4dc57eb24768a1/lib/elixir/lib/file.ex#L1796

And so on...

So I'd propose to call it `maybe_run`, just `maybe`, or something with 
`maybe`.

On Friday, June 5, 2020 at 9:48:56 AM UTC-4, Adam Lancaster wrote:
>
> We have something similar in our code base we called the Maybe.Pipe: ~>
>
>
> On 5 Jun 2020, at 14:41, Piotr Szmielew <p.sz...@ava.waw.pl <javascript:>> 
> wrote:
>
> maybe it should be called run_if? so, something like this:
>
> defmacro run_if(piped_value, condition, fun) do
>   quote do
>     if unquote(condition) do
>       unquote(fun).(unquote(piped_value))
>    else
>      unquote(piped_value)
>     end
>   end
> end
>
> and then used as:
>
> %{a: 1, b: 2}
>   |> X.run_if(1 == 2, &Map.put(&1, :foo, "foo"))
>   |> X.run_if(1 == 1, &Map.put(&1, :foo, "bar"))
> # => %{a: 1, b: 2, foo: "bar"}
>
> On Fri, Jun 5, 2020 at 3:27 PM José Valim <jose...@dashbit.co 
> <javascript:>> wrote:
>
>> Hi Riccardo,
>>
>> This is an interesting proposal! Unfortunately if the value you want to 
>> compute is expensive, then you need to fallback to the usual `if` approach. 
>> This is also specific to maps. It may be worth considering a more general 
>> purpose mechanism, for example:
>>
>>     map
>>     |> update_if(foo != nil, &Map.put(&1, :foo, foo))
>>     |> update_if(bar != nil, &Map.put(&1, :bar, normalize_bar(bar)))
>>
>> Being in Kernel also allows us to write it as a macro, which can be 
>> further optimized. Not sure if update_if is the best name though. 
>> Suggestions and comparisons to other languages are welcome. 
>>
>> On Fri, Jun 5, 2020 at 12:36 PM Riccardo Binetti <rb...@gmx.com 
>> <javascript:>> wrote:
>>
>>> Hi everybody,
>>>
>>> this is my first proposal so I hope I get the format right, I've already 
>>> checked in the mailing list and I haven't found similar proposals.
>>>
>>> *Problem*
>>>
>>> When manually constructing a map using external options or the result of 
>>> a pattern match on a struct, I often find myself in the situation where I 
>>> have to add a value only if it is non-nil.
>>>
>>> The possible approaches available today are these
>>>
>>>
>>> *Using if*
>>>
>>>
>>> def some_fun(s) do
>>>   MyStruct{
>>>     foo: foo,
>>>     bar: bar,
>>>     baz: baz
>>>   } = s
>>>
>>>   map = %{a: "hello", b: 42}
>>>
>>>   map =
>>>     if foo do
>>>       Map.put(map, :foo, foo)
>>>     else
>>>       map
>>>     end
>>>
>>>   map =
>>>     if bar do
>>>       Map.put(map, :bar, bar)
>>>     else
>>>       map
>>>     end
>>>
>>>   if bar do
>>>     Map.put(map, :baz, baz)
>>>   else
>>>     map
>>>   end
>>> end
>>>
>>>
>>> This is the obvious solution, but it gets very verbose very quickly
>>>
>>>
>>> *Populating the map and then filtering*
>>>
>>> def some_fun(s) do
>>>   MyStruct{
>>>     foo: foo,
>>>     bar: bar,
>>>     baz: baz
>>>   } = s
>>>
>>>   %{a: "hello", b: 42}
>>>   |> Map.put(:foo, foo)
>>>   |> Map.put(:bar, bar)
>>>   |> Map.put(:baz, baz)    
>>>   |> Enum.filter(fn {_k, v} -> v end)
>>>   |> Enum.into(%{})
>>> end
>>>
>>> This is more concise, but it creates intermediate maps that are 
>>> immediately thrown away. Moreover, if the initial map is very large, the 
>>> filter operation is expensive since it traverses the whole map.
>>>
>>>
>>> *Implementing a maybe_put helper function*
>>>
>>> def some_fun(s) do
>>>   MyStruct{
>>>     foo: foo,
>>>     bar: bar,
>>>     baz: baz
>>>   } = s
>>>
>>>   %{a: "hello", b: 42}
>>>   |> maybe_put(:foo, foo)
>>>   |> maybe_put(:bar, bar)
>>>   |> maybe_put(:baz, baz)    
>>> end
>>>
>>> defp maybe_put(map, _key, nil), do: map
>>> defp maybe_put(map, key, value), do: Map.put(map, key, value)
>>>
>>> This is the solution I end implementing almost always. It is present in 
>>> multiple modules across the codebase I work on (and/or put in a generic 
>>> Utils module), and talking with my colleagues I found out that is a utility 
>>> function that they also have to implement often and it has turned up at 
>>> least a couple times[1][2] also in the Elixir Forum.
>>>
>>> [1] 
>>> https://elixirforum.com/t/elixir-way-to-conditionally-update-a-map/17952/21?u=rbino
>>> [2] 
>>> https://elixirforum.com/t/is-there-way-to-create-map-and-conditionally-exclude-some-keys/23315/5?u=rbino
>>>
>>> This brings me to my proposal, which is a more generic version of 
>>> maybe_put.
>>>
>>> *Proposal*
>>>
>>> Add Map.put_if/4 to the Map module. This is more generic (and imho 
>>> clearer) than maybe_put and can be used to solve the same problem without 
>>> creating intermediate results and allowing the code to be clear and concise.
>>>
>>>
>>> def some_fun(s) do
>>>   MyStruct{
>>>     foo: foo,
>>>     bar: bar,
>>>     baz: baz
>>>   } = s
>>>
>>>   %{a: "hello", b: 42}
>>>   |> Map.put_if(:foo, foo, foo != nil)
>>>   |> Map.put_if(:bar, bar, bar != nil)
>>>   |> Map.put_if(:baz, baz, baz != nil)    
>>> end
>>>
>>> Let me know if you need any other information.
>>> --
>>> Riccardo
>>>
>>> -- 
>>> 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-l...@googlegroups.com <javascript:>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/f513b901-fd93-4f28-88a2-f496a3c84a21o%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/f513b901-fd93-4f28-88a2-f496a3c84a21o%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-l...@googlegroups.com <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4K_QVpD-eRG6JUOMYV5pVTLchpTgbO0fqN6pPCmuSL4NA%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4K_QVpD-eRG6JUOMYV5pVTLchpTgbO0fqN6pPCmuSL4NA%40mail.gmail.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-l...@googlegroups.com <javascript:>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/CANmTJ6thcegKJjb7aKPhtQoqfo5%3DCgJo2-KnORRg8B2UcEB%3D-A%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/CANmTJ6thcegKJjb7aKPhtQoqfo5%3DCgJo2-KnORRg8B2UcEB%3D-A%40mail.gmail.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/45a9ec20-f997-4fdf-a4c0-ea88388a8fabo%40googlegroups.com.

Reply via email to