I think this has been brought up a few times and not sure there's a great
need for it.  It can't (shouldn't) happen _that_ many times, because if
you're not going to do something with the result of a function the chances
are you should be bothering to do_something() to the function anyway.  And
even then there are a few other ways this can be done that are arguably
cleaner.

1.  You have to write "write_y()" function anyway, so create a version that
has a no-op version that simply returns the argument:

def write_y(y, arg0, arg1, skip \\ false)
def write_y(y, _, _, false), do: y
def write_y(y, arg0, arg1, _) do
 ....

2.  You can write an anonymous function inline that contains your logic
pretty easily, although I don't think this syntax is well-liked, it's at
least clear.

some_value
|> do_something()
|> (fn y ->
  if y_needed, do: write_y(y, arg0, arg1), else: y
end).()

3.  What you don't say whether or not the function called in the "then"
function actually returns the original piped value, or if it returns the
result of the "write_y" function.  There _has_ been discussion about a
"tap" function that would let you basically encapsulate the logic in the
previous inline function example but be _sure_ to always return the
original piped value (so you don't forget the "else: y" bit).  I don't
remember if that was something that eventually was decided or not, but it's
a simple function to write yourself if you really want it:

def tap(value, block) do
  block.(value)
  value
end

some_value
|> do_something()
|> tap(fn y ->
  if y_needed, do: write_y(y, arg0, arg1)
end)

The difference between #2 and #3 is what is ultimately returned if
"y_needed".  The "tap" function sees a lot more use cases, I think, because
"side effects" are a more frequent occurrence -- tossing something into a
job queue, writing off a log message that isn't just "IO.inspect",
triggering an asynchronous operation, etc.  Things where you want to do
something with an intermediate value but don't want to change it in the
process.

I'm hard pressed to come up with a really great example of where you may
want to conditionally do something to a value inline that isn't better
handled with functional logic.  The idea of "conditionally apply sales tax
to a price calculation" comes to mind, but you would encapsulate the logic
into the function anyway, because the actual sales tax rate is different
per state.  I'd expect that to be more like:

item
|> apply_quantity_discount(quantity)
|> apply_sales_tax(state). # apply_sales_tax would know whether or not to
do anything based on the state

You say you have to do this "often" -- can you give us some real-world
examples of your code logic that you feel necessitates this kind of thing?
I really can't think of too many, and wonder if maybe there's just a better
way for you to think about the problem in the first place?

...Paul



On Fri, Oct 8, 2021 at 3:59 AM 'Damir' via elixir-lang-core <
elixir-lang-core@googlegroups.com> wrote:

> Often I have a function that I want to apply to a pipeline conditionally.
> I'm forced not to either write a "maybe_do_x" function or use an inline
> check with then/2.
>
> Now that we have then/2, I'm thinking it might be nice to have then/3 so
> that we don't need "maybe_" functions anymore, improving composability.
> Example usage:
>
> y_needed = # true or false
>
> some_value
> |> do_something()
> |> then(y_needed, &write_y(&1, arg0, arg1) )
>
> --
> 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/9b4501b4-e114-4421-b61a-74240d160a15n%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/9b4501b4-e114-4421-b61a-74240d160a15n%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/CAD3kWz-Sy3NhDE6bitBCXva%2B99massw%3D%3DbFBC5Rcc1tLDfJK9Q%40mail.gmail.com.

Reply via email to