And if you want to see an example for a language that is not like that, look at Scala and ZIO (www.zio.dev). It is a library for pure functional programming, but look at the examples - those abstractions you mention are not there. The library really aims at making concurrent/async programming easier by leveraging pure functional programming but without crazy category theory stuff.
We need more practical pure functional programming libraries that focus on tackling problems with concurrent updates, streaming, state-changes etc. without forcing you to take a course in category theory beforehand.
That first example shows that the for syntax desugars to nested flatMap. Which is analogous to Haskell’s do notation, which desugars to nested bind.
The abstractions you said are not there, seem to actually be there in zio!
Strictly speaking that's wrong. Yes, ZIO is a monadic type. But you really don't need to understand monads to understand the example. In fact, the word monad does not even appear at all. Or would you say javascript also "explains a monad" when someone explains how to map/flatmap over an array? I doubt it.
> That first example shows that the for syntax desugars to nested flatMap. Which is analogous to Haskell’s do notation, which desugars to nested bind.
> The abstractions you said are not there, seem to actually be there in zio!
Again, those concepts are even in javascript. In fact, they are in every language. The question is if it is decided to make them explicit and reusable or not. And ZIO chose to not require any knowledge of them to be able to use the library - and that's what we are talking about here no?
Let's look at the code of flatMap that you are complaining about:
/**
* Returns an effect that models the execution of this effect, followed by the
* passing of its value to the specified continuation function `k`, followed
* by the effect that it returns.
*
* {{{
* val parsed = readFile("foo.txt").flatMap(file => parseFile(file))
* }}}
*/
def flatMap[R1 <: R, E1 >: E, B](k: A => ZIO[R1, E1, B])(implicit trace: Trace): ZIO[R1, E1, B] =
ZIO.OnSuccess(trace, self, k)
Where are monads, monoids, functors, ... here? They are not to be found. Replace "flatMap" with "then" and you pretty much have javascript's promises.By reading the docs I could easily recognize monads. If you replace “for” with “do”, they even have the same syntax! I could also see clear examples of things that were modeled as monoids and functors. I would claim that zio took inspiration from Haskell to model the composable parts.
Hey, I’m not complaining about any code, and specially not flatMap. I think it is a great design. It is the bind operator in the monad class in Haskell, and there is also syntax sugar to hide it and make it look like imperative code, just like Haskell. I like that!
It seems to me that it is fair to say that the abstractions are useful as you recognize in your previous comment. Maybe you just have an aversion against the abstraction names, or the way many Haskell-related articles go on and explain them… which is fair enough.
I learned Haskell without having to understand those concepts. I could just used them by experimenting with what was possible and seeing examples from other people. It was not particularly difficult. So, as you also figured out with zio, understanding the abstractions is not a requirement for using them.
> would you say javascript also "explains a monad" when someone explains how to map/flatmap over an array?
On the other hand, if you have to explain how the for/yield in zio and why it works for so many different types, you have to basically explain Monad using another name.
But again, that's not happening.