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.