Thank you for providing a concrete example.

Also subjective but I find the following more readable

  |> then(&if(modified_since, do: Req.put_header(&1, "If-Modified-Since",
modified_since), else: &1))

than

  |> then(&Req.put_header(&1, "If-Modified-Since", modified_since), if: fn_
-> modified_since end)

But perhaps this case might benefit from introducing a private function
rather than relying on `then`, especially if this is a recurrent use-case
in your module/project:

defp maybe_add_header(req, _key, nil), do: req
defp maybe_add_header(req, key, value), do: Req.put_header(req, key, value)

...
|> maybe_add_header("If-Modified-Since", modified_since)
|> maybe_add_header("X-Entity-Id", entity_id)

It should also be easy define your own then_if/3 macro if you really prefer
the clojure style.


Le dim. 4 août 2024 à 09:59, Caio Oliveira <caio...@gmail.com> a écrit :

> True, although personally I find the one-line `if` kind of confusing,
> especially when I was newer to the language.
>
> > Additionally, your suggestion only implies what happens if `pred` is
> falsy while mine is clear.
>
> This almost convinced me, to be honest! But on the flip side this makes it
> possible for you to forget to add a `else` clause, and just end up with a
> `nil` that is potentially hard to find where it came from.
>
> Jose replied this in the PR (including here to centralize the discussion
> and not spam the PR and his email there):
>
> > I personally would prefer to write the original code or use no pipeline
> at all. I don’t think the gain in conciseness justifies the loss in
> readability.
>
> I'd say I agree with it 99% of the time, but there's this 1% that makes me
> miss Clojure's `cond->` <https://clojuredocs.org/clojure.core/cond-%3E>.
> The concrete example that made me write this PR was this: I'm writing a
> small internal library to build requests for a third party service. There
> are some options that, if included, requires me to add headers to a
> request. The code looks something like this:
>
> ```elixir
> def request_entity(opts) do
>   modified_since = Keyword.get(opts, :modified_since)
>   entity_id = Keyword.get(opts, :entity_id)
>
>   Req.new(url: "example.com")
>   |> add_x()
>   |> authorize()
>   |> add_body()
>   |> then(&if(modified_since, do: Req.put_header(&1, "If-Modified-Since",
> modified_since), else: &1))
>   |> then(&if(entity_id, do: Req.put_header(&1, "X-Entity-Id", entity_id),
> else: &1))
>   |> Req.request()
> end
> ```
>
> And I'd much rather write something like this instead:
>
> ```elixir
> def request_entity(opts) do
>   modified_since = Keyword.get(opts, :modified_since)
>   entity_id = Keyword.get(opts, :entity_id)
>
>   Req.new(url: "example.com")
>   |> add_x()
>   |> authorize()
>   |> add_body()
>   |> then(&Req.put_header(&1, "If-Modified-Since", modified_since), if:
> fn_ -> modified_since end)
>   |> then(&Req.put_header(&1, "X-Entity-Id", entity_id), if: fn _ ->
> entity_id end)
>   |> Req.request()
> end
> ```
>
> You can see conciseness is not the point*, but readability, robustness and
> convenience (a very subjective feeling, so feel free to ignore the last
> one).
>
> Lastly, I know I could change the code in a million ways to avoid the
> pattern altogether, maybe even resulting in a cleaner result, but I feel
> this small addition would be a nice to have, and is something I miss, even
> if rarely.
>
> * I left the conciseness out of the picture because I think it's way less
> important, but it does play a bit of a part. The actual example ends up
> needing to break the `if` into more lines, which doesn't read as good in
> the middle of the piping.
> Em sábado, 3 de agosto de 2024 às 19:09:10 UTC-3, gva...@gmail.com
> escreveu:
>
>> You can already capture the `if` and do it as a one-liner
>>
>> x |> then(&if(pred(&1), do: f(&1), else: &1))
>>
>> so you don't gain much yet add more complexity. Additionally, your
>> suggestion only implies what happens if `pred` is falsy while mine is
>> clear.
>>
>> -Greg Vaughn
>>
>> > On Aug 3, 2024, at 4:16 PM, Caio Oliveira <cai...@gmail.com> wrote:
>> >
>> > x
>> > |> then(fn val ->
>> > if pred(&1) do
>> > f(val)
>> > else
>> > val
>> > end)
>> >
>> > Into this:
>> >
>> > x |> then(&f/1, if: &pred/1)
>>
>>
>> --
> 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/3c468ed7-1db6-46e3-bf23-45c21e501b3bn%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/3c468ed7-1db6-46e3-bf23-45c21e501b3bn%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/CANnyohay83mzBJRgz%3Dy8RZ6cp257u4t8zSfyMKMOfqmSTMvY2A%40mail.gmail.com.

Reply via email to