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.