News for hackers. Stuff that matters.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by yoz-y on Saturday June 26, 2021 @01:04AM (#27639267)
Wait. Assuming one does not need or want to learn Haskell, what would then be a purpose of learning about monads?

There seems to be a disproportionate amount of tutorials about monads. Not being able to provide sufficient amount of examples in other languages makes monads seem quite less useful. Maybe next article to write is “why should you learn about monads”.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by mrspeaker on Saturday June 26, 2021 @02:34AM (#27639660)
If you never want to learn Haskell (or PureScript or similar) then the author even says in the `If They're So Wonderful Why Aren't They In My Favorite Language?` section:

    "If you don't need IO sequencing, or purity because your language doesn't care about purity, or the list implementation's nondeterminism because that's a parlor trick, or STM because your ecosystem doesn't use it... there's not much point to worrying about it. Monad implementations in languages other than Haskell fail to take off because there generally isn't even a single thing that is improved by working with it through a monad interface, let alone a family of such things."

    "[...]It's definitely an interesting idea, and if you are a curious programmer, it's worth learning about this particular interface and what it can do. But it's not something you generally directly take back to your language"
Re:Functors and Monads for People Who Have Read Too Many “Tu... by morelisp on Saturday June 26, 2021 @07:54AM (#27641110)
There are two subtly different things here, "monads" as a concept and specific monads. If I ask you, what's the thing in common between async functions, nullable types, exception handling, sequenced evaluation, and arrays, and you only know, say, Java, Scheme, and Python - you'll probably not see anything.

Nonetheless, these are all monads, and learning specific monads helps in lots of other languages. Optionals are nice in Java. Arrays in Lisps. Error handling in Scala. But the "universality" of monads escapes these languages. I would kill for better monadic error handling in Go, but conversely I would have little use for monadic I/O or futures.

The critical mental step is seeing the commonality in all of these, which is really only possible in languages at that level of type sophistication. And necessary in Haskell where the particular combination of purity, laziness, and HKTs means monads are the only way decent way to do most of these. Once you see that commonality you can develop tools - patterns of mental reasoning about code and idioms for writing code - you can also use when dealing with the specific monads or nearly-monads in other languages. But you can't show that property in examples in a single other languages, and it's difficult to show how some deep structure is shared in examples spanning five languages.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by yoz-y on Monday June 28, 2021 @09:50AM (#27661941)
I think that in the end I would wish for an article that distills the last part. "How to benefit from monadic nature of various concepts in any language". I believe that it goes beyond flatMapping over async functions, nullable types and arrays, and using higher order functions.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by lmm on Saturday June 26, 2021 @02:25AM (#27639634)
Monads are a very effective technique for expressing custom requirements in your type system, e.g. "this function must be called only in a database transaction", "this function writes an audit log entry", "this function requires this level of authorization". The kind of thing you might think you would have to do via AOP/decorators/monkeypatching, you can usually do in plain old code (with all the attendant advantages) via a monad.

If your type system can't express them then you lose most of the advantages and they're pretty pointless.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by calo_star on Saturday June 26, 2021 @04:35AM (#27640212)
I find this perspective intriguing, can you elaborate on that? For example why `m a -> (a -> m b) -> m b` but not something else?
Re:Functors and Monads for People Who Have Read Too Many “Tu... by uryga on Saturday June 26, 2021 @09:32AM (#27641653)
> why `m a -> (a -> m b) -> m b` but not something else?

it's basically continuation-passing-style (`a -> m b` is the "continuation"), you might as well ask "why can you represent so many control-flow things using CPS?". idk why, but you can!

from another angle, you could compare Monad with the less powerful Applicative. a formulation[0] that's easier to parse than the usual one[1] is:

  class Functor f => Applicative f where
    unit :: f ()
    pair :: f a -> f b -> f (a, b)
if you're familiar with JS Promises, a rough analogy would be

  >>=  (Monad)        Promise.then
  pair (Applicative) ≈ Promise.all
  unit   (Applicative) =
  return (Monad)       = Promise.resolve
ignoring parallelism, you can implement Promise.all using Promise.then, but not the other way around.

---

[0] Called "Monoidal" here: https://stackoverflow.com/q/45267953 [1] https://en.m.wikibooks.org/wiki/Haskell/Applicative_functors...

Re:Functors and Monads for People Who Have Read Too Many “Tu... by lmm on Saturday June 26, 2021 @06:07AM (#27640642)
Some people describe monads as "programmable semicolons" - they're pretty much the general concept of sequencing, "do this then do that", or indeed of imperative code. I don't think they're necessarily the ideal abstraction - something like ArrowChoice is "better" in a lot of cases - but in practice they seem to come up a hell of a lot, you can represent almost anything as a monad.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by wyager on Saturday June 26, 2021 @09:16AM (#27641555)
Why monads and not something else? Because monads appear to be a/the mathematical structure underlying the denotation of programs with effects.

Why that type signature? You only have two options: that, or m (m a) -> m a. The former is more popular for ergonomic reasons mostly. It doesn’t really matter.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by rocqua on Saturday June 26, 2021 @09:36AM (#27641684)
Because so many types above are m of something. You as a programmer get to decide how that m type works, so you have a lot of control there.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by herbstein on Saturday June 26, 2021 @01:12AM (#27639294)
The point about Haskell is that it forces you to, or at least heavily nudges you to, understand monads and the rest of the typeclass hierarchy. However, you use the properties of monads all the time. The Stream APIs in JAVA and LINQ in C# are examples of abstractions built around Monads and their properties.

The definition of a monad, as it relates to programming, emerges when you realize that an Option type, a Result/Either type, a List type, and a bunch of other non-container types all have the equivalent of a `flat_map` function. Write out a few mathematical rules for how a well-behaved implementation should compose and you have a Monad and its rules.

This is why another approach to learning monads that isn't focused on the theory introduces it as a design pattern instead. I find this to be great for intuition but horrible for understanding personally, having used both approaches to teach people about Monads IRL.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by alephu5 on Saturday June 26, 2021 @11:02AM (#27642453)
There are many examples of monadic patterns used in other languages, in particular to encapsulate failure or nullable values. I've also seen a lot of codebases that have implemented a custom "pipeline" class that can be composed together, such that some transformation or effect occurs every time a value passes from one pipeline to another. These are usually monads too, allowing for some minor deviations from the formal definition.

Nevertheless language ecosystems outside Haskell, scala and F# don't recognise this as a general programming pattern, although given the current direction towards FP in the JavaScript and rust communities I think it's a matter of time.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by sfvisser on Saturday June 26, 2021 @02:29AM (#27639642)
Monads (and functors and applicative) are definitely useful outside of Haskell.

At first glance monads seem less useful in languages with builtin mutable state, and freely allowing side effects. However, if you’re writing somewhat more high-level domain specific code there are plenty of concepts that can be modeled using functors and monads very elegantly.

Parser combinators, distributed data fetching, reactive data streams, composable tree traversals, etc

I use them all the time in for TypeScript.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @03:02AM (#27639788)
If monads exist outside of Haskell, why isn't there a text which explains them with out Haskell knowledge? Where would I find such a text and description?

I would really like to understand what they are, but so far have not been able to find any explanation which tries to explain them in terms of english, math or some commonly known programming language.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by Huggernaut on Saturday June 26, 2021 @03:17AM (#27639857)
This is probably the best resource I've come across for discussing this subject: https://fsharpforfunandprofit.com/posts/elevated-world/
Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @04:02AM (#27640057)
Thanks, but the article loses me at what this "elevated world" is. It doesn't even try to explain what it is and quickly goes over to F# syntax, which I don't understand. Why is there no explanation in the terms of English, math, and any common programming language? If Functors and Monads are real concepts, they should be describable in the terms listed above, if they are only describably in terms of functional languages, I would consider them a pure artifact of those languages :)
Re:Functors and Monads for People Who Have Read Too Many “Tu... by aszen on Saturday June 26, 2021 @05:29AM (#27640443)
There's a problem here as the author himself notes.

I can provide you a simple example of a function with monadic interface, you will understand it any language but that will not actually help you to conceptualize the idea of monads and influence your thinking.

You will just think that's simple, whats the fuss about it and miss the pattern altogether.

Imagine asking the user to provide a number, in most languages you will get a `string | null` value and you wish to get a real number from it by parsing the string if the user entered it.

In this case assuming you have a function `parseNo` that goes from `string -> int | null` you can create a special function which takes a `string | null` value along with the `parseNo` function and gives you back `int | null`. S

Turns out that function can be defined for many different data types and it has special useful properties.

In this case it allows us to compose functions neatly, without having to do a whole bunch of null checks.

But in other scenarios it can do a lot more.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @09:46AM (#27641792)
Sounds like you are describing high order functions as they are known from Lisp?
Re:Functors and Monads for People Who Have Read Too Many “Tu... by aszen on Saturday June 26, 2021 @03:50PM (#27645203)
Yes higher order functions. A function that takes a function as an argument or returns a function. In lisp you can think of a higher order function as taking data, processing it and then returning it just like any other normal function because code is data.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by samhh on Saturday June 26, 2021 @06:28PM (#27646537)
You have a container with `a` inside, let's call the container `m`. You have `m a`.

You can provide a function with the type signature `a -> b`. With this we run the function underneath `m` and map `m a -> m b`.

Concretely this might be with for example lists, where given a function `Int -> String` I can map `[Int] -> [String]`. What the functor abstraction gives you is a consistent, lawful way to define this phenomenon for virtually every type you'd ever want to "map". Likewise monads for "flat mapping".

This explanation was 90% accurate. What's missing is that not every functor or monad is a "container", for example Haskell's `IO`, which rather represents an action of sorts to impurely get a value. But the intuition will build all the same if you play with it a bit. It's all in the type signatures.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by MauranKilom on Saturday June 26, 2021 @12:37PM (#27643362)
Say you have a source of A, and a way of turning an A into a source of B. An operation that uses these two inputs to produce a source of B is a monad.

This is about 90% of the way there (and TFA actually contains very similarly phrased description, right before the monad definition you complained about).

The problem is that English does not have the right words to describe the abstract idea behind "source", "way of" and "operation" precisely and rigorously.

Regarding "any common programming language": In a way, this is like trying to explain a concept like, say, "the adjoint operator" [0] to someone only aware of integers. Or trying to explain the idea of the Liskov Substitution Principle [1] to someone who just learned assembly.

In each case above, the language used to describe the concept is multiple layers of abstraction too low to succinctly ping down the concept in question. Haskell brings (or rather is) a very rich language suited specifically for accurately describing the elements involved. That's why 1) the concept of a Monad is visible/cleanly expressible in the first place, and 2) people use it to explain the concept, even when (like this blog post) not aiming at a Haskell (or Haskell learner) audience.

Disclaimer: I'm just a lowly OOP programmer, not written a line of Lisp or Haskell in my life. Watching from the sidelines for now.

[0]: https://en.wikipedia.org/wiki/Hermitian_adjoint

[1]: https://en.wikipedia.org/wiki/Liskov_substitution_principle

Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @01:07PM (#27643637)
Say you have a source of A, and a way of turning an A into a source of B. An operation that uses these two inputs to produce a source of B is a monad.

Did you mean to write "Say you have a source of A, and a way of turning an A into a B. An operation that uses these two inputs to produce a source of B is a monad"?

What exactly do you consider a "source"? And the way of turning an A into a B I would call a function. And combining the "source of A" with a function that converts A's into B's, a concationation or composition of functions, or a way of currying.

And yes, I am fully aware, that you sometimes need to learn the vocabulary to have a minimum discussion. But considering I have a degree in math and CS, have learned at least 10 programming languages, especially Lisp with all of its contexts, I am highly suspicious about something that cannot expressed in plain language. But thanks, your explanation comes closest I have seen so far.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by MauranKilom on Saturday June 26, 2021 @05:13PM (#27645929)
> Did you mean to write "Say you have a source of A, and a way of turning an A into a B. An operation that uses these two inputs to produce a source of B is a monad"?

No. That would be the Functor concept explained in TFA. A Monad is specifically what I wrote.

> And combining the "source of A" with a function that converts A's into B's, a concationation or composition of functions, or a way of currying.

Yes, pretty much. See the article (where one of the main points is specifically that the functor concept is not a highly complex thing. Just a name for a kind of thing - an abstraction).

> What exactly do you consider a "source"?

That's exactly the point where the "genericness" of the concept (consider: it originates from category theory) precludes discussing it in more specificity. It could be a Maybe<A> (std::optional in C++), it could be a List<A>, it could be a PotentialFutureUserInput<A> (aka IO in Haskell), it could be a (C#) Enumerable... Anything that "wraps" (in any sense) another type. A functor allows you to apply a function that transforms the inner type into another without leaving the wrapper. A monad allows you to apply a function to the inner type, transforming it into a different now wrapped type, with the monad implementation taking care of "flattening" the wrappers. I will avoid the attempt to come up with an example, seeing as the article also criticizes the abundance of bad monad examples.

Here, I've written a C++20 concepts version of Monad. Well, I hope I did. But even if correct, it's just not something C++ can express well, much less use well: Since functions are not first-class citizens, you can't spell "a function from A to M<B>" in a way the compiler can deduce. That's why you need the extra template argument F and corresponding constraint FAMB.

https://godbolt.org/z/b3PoPYeE9

Re:Functors and Monads for People Who Have Read Too Many “Tu... by pests on Saturday June 26, 2021 @05:12AM (#27640368)
There isn't one unique elevated world, as he goes on to say. Two he lists we are familiar with - options and lists. If you've ever used Option(Some|None) and pulled out a value from Some - the Option is the elevated world, the Some|None is the elevated value.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by loopz on Saturday June 26, 2021 @09:50AM (#27641834)
In most languages you will lack the Monad type and helper functions, and you'll have available many shortcuts that undermine efforts to set up monadic expressions.

So something can behave similarly to a monad, but the type systems don't stop you self-sabotaging your code or misunderstanding good composition.

Best way to learn is to learn Haskell deliberately. Better than Go, the language forces you to compose better code, and even learn the values of FP.

If one is uninterested in learning CS or expanding one's toolbelt, it'll take some years until industry catches up.

Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @09:54AM (#27641866)
So you are saying you cannot describe what a Monad is without the presense of a FP language?
Re:Functors and Monads for People Who Have Read Too Many “Tu... by loopz on Saturday June 26, 2021 @11:07AM (#27642498)
I didn't say that. Learning Haskell may help the budding learner, though won't enforce the monadic laws.
Re:Functors and Monads for People Who Have Read Too Many “Tu... by wyager on Saturday June 26, 2021 @09:18AM (#27641569)
The entire body of category theory is where all of this stuff comes from originally, not Haskell.

> tries to explain them in terms of english, math

There are a million English-language blog posts, and it’s a mathematical concept. Just look up “monads are monoids in the category of endofunctors” if you want more of that…

Re:Functors and Monads for People Who Have Read Too Many “Tu... by _ph_ on Saturday June 26, 2021 @09:59AM (#27641910)
I was looking for a simple explanation about what a Monad could be, not a mathematical theory.