Hello!

As a data point JavaScript, TypeScript, Rust, Gleam, and
Rescript/ReasonML/Bucklescript all use then or and_then as the name for
that monadic function in their standard libraries.

It seems to be a fairly common name these days so I'd probably favour using
a different one to avoid any confusion.

Cheers,
Louis


On Tue, 29 Dec 2020, 12:30 José Valim, <jose.va...@dashbit.co> wrote:

> Hi Marten,
>
> Thanks for the feedback!
>
> The only reason I picked "then" is exactly because, if we ever introduce
> something akin to monads, I wouldn't pick "then" because I don't think it
> is clear enough on its monadic value. Also note that:
>
> 1. "andThen" in Scala is function composition and not bind. bind is
> flatMap (which I personally prefer)
>
> 2. "andThen" in Elm is indeed bind but it is not polymorphic, so you have
> Task.then, Maybe.then, etc. Therefore, even if we decide to go with "then"
> in the future, there is no naming conflict, unless we choose a polymorphic
> monad implementation. In fact, Kernel.then could then be used as an
> introduction to other monadic modules.
>
> So overall I think we are clear. This will be a bad choice only if all of
> the below are true:
>
> 1. We introduce monads
> 2. We pick "then" as the name for bind
> 3. Monads are polymorphic so we are accessing them via an imported "then"
> instead of qualified per module
>
> Happy holidays!
>
> On Tue, Dec 29, 2020 at 12:32 PM w...@resilia.nl <w...@resilia.nl> wrote:
>
>> 1. tap:
>> I think adding tap will be very useful. I often am doing something like
>>
>> ```
>> ast = quote do ... end
>> IO.puts(Macro.to_string(ast)
>> ast
>> ```
>> when debugging macros.
>> Being able to change this to
>> ```
>> quote do ... end
>> |> tap(&IO.puts(Macro.to_string(&1))
>> ```
>> will be very welcome. :-)
>>
>> 2. then:
>> What José is referring to (when talking about `then` in relation to other
>> languages where it is also used for e.g. promises) is the monadic 'bind'
>> operation. You might also know it as `>>=` as well as `andThen`:
>> - `>>=` is the (non-descriptive) symbolic name that is used in Haskell,
>> PureScript, and F# as well as many papers.
>> - `bind` is the name given to above operation. It is also a
>> frequently-used name whenever an operator is not used. In fact, `bind` is
>> used in the Elixir ecosystem right now. One example that comes to mind is
>> `StreamData`. There are probably others.
>> - `andThen` sees usage in Scala, Elm and as already mentioned by José in
>> many other contexts whether they deal with only promises, only parsers,
>> only nondeterminism, etc... or monads in general.
>>
>> Even if it is more verbose, I think the name `andThen` is more
>> descriptive than plain `then`. Therefore I prefer `andThen`.
>>
>> But rather I'd not add it at all:
>> This proposed function will only be specialized to the "identity monad".
>> The bind operation is the place where the unwrapping of the monadic value
>> ought to happen. The identity monad is the one case where there is nothing
>> to unwrap.
>> `then/2` as described is a function that does nothing over using the
>> function directly, except for "circumventing" the parsing precedence issue
>> of `&` vs `|>` (if you need a refresher, find prior discussion about
>> allowing anonymous functions and captures in pipes here
>> <https://github.com/elixir-lang/elixir/issues/10154>).
>> `then/2` only exists for improved syntax, not for improved semantics.
>> The fact that we are specializing it for this single syntactic purpose
>> makes me consider that maybe we'd be better off choosing a different name
>> that does not have this pre-existing meaning attached.
>>
>> Even if you're unfamiliar with monads or algebraic datatypes in general,
>> you'll be able to understand the problem of restricting a general operation
>> to one specific case.
>> It's a bit like saying "Let's add a `Kernel.sum/1` that sums (only) lists
>> of integers." It 'works' but what about lists of floats? sets of integers?
>> lists of decimals? etc.
>> There is a lot of missed potential.
>> There is a high possibility that a decision like this cannot be extended
>> or altered later on in a backwards-compatible way.
>> There is a high likelihood of people trying to use it in contexts where
>> it cannot be used and being confused by it or introducing bugs.
>>
>>
>> So I'd seriously consider using a different naming scheme for `then`.
>> I'd prefer a simpler name with less of a pre-existing meaning.
>> Possibly just `fun/2`.
>>
>>
>> Happy holidays! :-)
>>
>> ~Marten/Qqwy
>> On Tuesday, December 29, 2020 at 10:47:17 AM UTC+1 José Valim wrote:
>>
>>> I propose we simply add two functions to Kernel: tap and then.
>>>
>>> 1. tap receives an anonymous function, invokes it, and returns the
>>> argument. It can be found in Ruby and .NET Rx.
>>>
>>> 2. then receives an anonymous function, invokes it, and returns the
>>> result of the anonymous function. It will be how we can pipe to anonymous
>>> functions in Elixir. It is named andThen in Scala and known as then in many
>>> promise libraries across ecosystems.
>>>
>>> I think this can improve the piping experience considerably while
>>> keeping things functional.
>>>
>>> On Tue, Dec 29, 2020 at 4:20 AM Zach Daniel <zachary....@gmail.com>
>>> wrote:
>>>
>>>> That takes it a bit too far for my taste. That part can easily be done
>>>> by passing an anonymous function and calling a series of functions.
>>>>
>>>> On Mon, Dec 28, 2020 at 9:55 PM Kevin Johnson <johnson7...@gmail.com>
>>>> wrote:
>>>>
>>>>>  I would prefer to introduce a general approach to this, such that:
>>>>>
>>>>> How general do you want it to be?
>>>>> Is this to cater solely for conveniently inlining side-effects; e.g.
>>>>> write to log, network, console or are there other use-cases that you
>>>>> envision?
>>>>> Do you envision inlining multiple side-effects:
>>>>> `|> tap(&Map.keys/1, [&IO.inspect/1, &KafkaEx.produce("foo", 0,
>>>>> &Poison.encode!(&1)), ...])` to facilitate some fan-out strategy with
>>>>> perhaps some desired options?
>>>>>
>>>>> --
>>>>> 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/CAAkfbUr9Ud1iKo0X1bCu1tcL5V1M-Z0um6-8JyFA0kOeh7fUmA%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAAkfbUr9Ud1iKo0X1bCu1tcL5V1M-Z0um6-8JyFA0kOeh7fUmA%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-co...@googlegroups.com.
>>>>
>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAK-yb0CYHpkZ5-qhM3CMx-VcUnkk16SC55_hOK-b%3DSPg%3DFzqXA%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAK-yb0CYHpkZ5-qhM3CMx-VcUnkk16SC55_hOK-b%3DSPg%3DFzqXA%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/4375daa4-9e65-4f4c-95a1-2d9147718d48n%40googlegroups.com
>> <https://groups.google.com/d/msgid/elixir-lang-core/4375daa4-9e65-4f4c-95a1-2d9147718d48n%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/CAGnRm4Jo-z4oGUimj0GZTL1HD8sFi91aWNTSvkLLkAiB63egpg%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jo-z4oGUimj0GZTL1HD8sFi91aWNTSvkLLkAiB63egpg%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/CABu8xFAuRPQ1hgoRJ6UFn5YWd%2BJ-%3Da812LJ9NTy3SfLr%3D5eTzA%40mail.gmail.com.

Reply via email to