Live data from Hacker News

Monads are monoids in the category of endofunctors

sambernheim.com

101–110 of 241 posts

Re: Monads are monoids in the category of endofunctors

#101
post #8
post #5

Wait, a functor is just a pure unary function? And an endofunctor is just one of those where the argument type and return type are the same? This could have been explained to me years ago, in five minutes? Sometimes it makes me mad that so much confusion (and as another commenter put it, gatekeeping) has been sown in FP circles through the invention of pointlessly-obfuscated terminology for everything (and through -…

Kind of reminds me of an old saying I heard somewhere, that I'll paraphrase here: "novice writers use little words, intermediate writers use big words, and expert writers use little words." Like, it's fun to communicate in technical jargon -- and personally I'm quite proud of the vocabulary I have built up over time -- but you are totally correct in that it serves as a gatekeeper for an in-group to retain its dominan…

I very much agree with part of your point, especially the novice-intermediate-expert part on jargon. I generally favor wording that is as simple as possible, but no simpler. Sometimes technical precision is important, and when talking to colleagues and other people that are on a similar technical proficiency level as me I prefer concise and informative words. I'd rather say "ARP poisoning" than "network attack", because the latter loses information, but would obviously use the latter to muggles.

I don't agree that having a domain jargon that is technical and concise is "gatekeeping" for functional programming. If you are a frontend developer you need to know what the DOM is. If you are a Haskell programmer you need to know what a monad is. The fact that you don't get the Haskell jargon "for free" coming from other programming disciplines doesn't mean that it's "gated", it just means you need to learn. And there are plentiful resources to help you with that, countless "how to understand monads" articles and so on. In my experience, the Haskell community is perhaps the single most welcoming and helpful programming community. There's even a handy guide with big, friendly drawings.

Re: Monads are monoids in the category of endofunctors

#102
post #61

Earlier quoted context omitted.

So you would say the same for programming in general then? Should programmers not use the word "function" because that word is foreign to non-programmers and might push them away?

Some terms are used for radically new concepts with no analogue, some terms refer almost exactly to concepts people already know, and some terms refer approximately to concepts people already know (and could be explained as "like X but with these differences") For example: I might explain the programming concept of a function as "like the equations you remember from math class" (for pure functions) or "like a recipe"…

It often makes me very mad that so much gatekeeping has been sown into programming circles through the invention of pointlessly-obfuscated terminology for everything. Programmers are really arrogant most of the time, they dont want to teach beginners their craft so they just make everything difficult on purpose. They are like medieval priests yada yada.

Does what I write above bother you at all? Do you feel that it apply to you and programmers in general? Because that is the kind of generalization you are doing to another group of programmers.

I see a lot of functional programmers spending a lot of time trying to teach others. I also see a lot of people not wanting to spend any time learning so they just talk down on functional programmers, and I think its unnecessary.

Re: Monads are monoids in the category of endofunctors

#103
post #89

Earlier quoted context omitted.

Isn't it more like, no mutation ?

Not exactly. When using the I/O monad in a pure language like Haskell, your code doesn't directly have side effects, instead you're building a container (a monad) of instructions of what side effect having operations to do, and what should be done with the results. The Haskell runtime then takes this monad and unwraps it layer by layer, each layer executing the side effect having instruction and using the results of…

> instead you're building a container (a monad) of instructions of what side effect having operations to do, and what should be done with the results. The Haskell runtime then takes this monad and unwraps it layer by layer, each layer executing the side effect having instruction and using the results of the side effects as input for unwrapping the next layer.

Note that this is the implementation of a specific monad - not all monads are like that. Many monads are not containers, and some can't be "unwrapped" at all.

> Note that the effect of this system is exactly the same as a language that does have side effects. They are functionally identical. The nicety of Haskell's purity comes from how the monads allow you to organize your code.

You might enjoy "the C language is purely functional": http://conal.net/blog/posts/the-c-language-is-purely-functio... . The useful part of purity is that the pure form of Haskell has some interesting algebraic structure (in particular there are a lot of ways to refactor code while preserving its semantics), whereas the pure form of C or javascript does not have many equivalence laws.

> By the way, not sure if this is controversial but JavaScript's I/O system is a lot like the I/O monad. I/O doesn't really get executed immediately, and you can't directly operate on the results of I/O. The runtime executes the I/O after all JavaScript's been executed, and you use callbacks to tell the runtime to do whenever the I/O data returns.

I think you're conflating interface and implementation here. Javascript I/O is implemented similarly to Haskell I/O in some ways, yes. But the interesting part of Haskell's I/O isn't the implementation, it's the (pure) API that it uses, and Javascript has nothing like that.

Re: Monads are monoids in the category of endofunctors

#104
post #49

Earlier quoted context omitted.

Communication is a two-way street. When someone is making an effort to learn, most FP advocates will happily make an effort to teach. But someone who comes in with guns blazing doesn't get to complain about being met with hostility, and if telling someone they're wrong when they're wrong is gatekeeping then it's a kind of gatekeeping that we need.

I would say the person you're responding to didn't come in "guns blazing". They seemed legitimately eager to learn, and expressed gratitude that the person that wrote the blog post used language they could understand. Now, I would say you showing up and openly disparaging both the blog and the person you responded to qualifies as "guns blazing".

They said "It's like when the medieval Catholic Church refused to print a bible in anything but Latin so that they'd remain the sole authority on its content." and concluded with "shame on those who maintain this status quo." That's pretty "guns blazing" in my book.

Re: Monads are monoids in the category of endofunctors

#105

Earlier quoted context omitted.

Some terms are used for radically new concepts with no analogue, some terms refer almost exactly to concepts people already know, and some terms refer approximately to concepts people already know (and could be explained as "like X but with these differences") For example: I might explain the programming concept of a function as "like the equations you remember from math class" (for pure functions) or "like a recipe"…

It often makes me very mad that so much gatekeeping has been sown into programming circles through the invention of pointlessly-obfuscated terminology for everything. Programmers are really arrogant most of the time, they dont want to teach beginners their craft so they just make everything difficult on purpose. They are like medieval priests yada yada. Does what I write above bother you at all? Do you feel that it a…

Generalizations are always imperfect, and I felt I was explicit about the fact that there are exceptions (like the OP).

I'll admit my emotions got a little heated. I get really frustrated thinking about all the potential out there that gets wasted just because of gaps in communication (willful or otherwise), and not because of capacity for understanding. And this very comments section demonstrates the unwillingness by at least some members of the FP community to put things into terms that would help with that problem, so I do feel justified talking about the community as having an issue. Whether they represent a majority or a vocal minority is not something I can say with confidence, though I still feel like I qualified my original statements sufficiently.

Re: Monads are monoids in the category of endofunctors

#106
post #97

Earlier quoted context omitted.

So monad is used to construct a new Type dynamically instead of writing it? And functor is also the same?

Not exactly dynamically - both a monad and a functor have to be a kind of "function" from type to type. The most common kind is a generic type with one type parameter. (e.g. you can see "List" as the "constructor" that takes "String" to "List ", takes "Int" to "List " and so on)

Many thanks!! So is it something like

Class> thisistypeconstructor(Class strClass)

And if I generify the types above, maybe something like

thisistypeconstructor()

Re: Monads are monoids in the category of endofunctors

#107
post #46
post #19

Earlier quoted context omitted.

I’m helping the dude improve his writing with a short and minimally critical comment. Hall monitor elsewhere.

How can you tell that he's well dressed or lives in a city? https://en.m.wikipedia.org/wiki/Dude

I disagree that it’s a relevant comparison, but kudos for the wit regardless.

Re: Monads are monoids in the category of endofunctors

#108
post #41

Earlier quoted context omitted.

Functors are type constructors, not functions (which map values). But you could be forgiven the misunderstanding, because it is easy to trip over this distinction given the identical syntax. So, to make this absolutely clear, a monad is a type constructor in functional programming. This is why I personally prefer the more “creative” explanations of monads, because they attempt to explain what the monad is doing to th…

> a monad is a type constructor Now explain what a "type constructor" is, otherwise these words are worthless.

Here's how I like to think about things:

Values are things. Concrete. Since we are manipulating computers, a value is really just some abstract symbols--1s and 0s occupying a slot in memory. The meaning of the symbols exists on a higher level, what we usually call semantics.

Types are a well-studied method to attach semantics to blocks of otherwise meaningless (but concrete!) symbols. By declaring a variable (which is just a pointer to a memory block containing arbitrary symbols) is of type Int, we are establishing that in the context of the program, the symbols occupying that memory block are to be interpreted as the encoding of an integer.

Functions are transformations of values. They manipulate concrete things to produce other concrete things. By specifying the input and output types, we ensure that the transformations applied by our functions are only used on the right kinds of things, and we also know what kind of thing we will get out of the function. Mind you, these things are still all just arbitrary symbols in blocks of memory, but now we know how to semantically interpret them based on the function's specification.

Type constructors are also transformations, but of types. That is, we use type constructors to modify or enhance the semantics of a basic type. Functors are essentially type constructors that extend function semantics as well: if F is a functor, then you can "lift" any function from type A to type B into a function from type F to type F. (Note that I'm using the commonly recognized "generic type" angle bracket notation to deliberately avoid the confusion of Haskell's pedantically minimalist syntax.)

I think this description provides a much more intuitive path to the understanding of, say, a list as a functor. A "list" is a generic structure that can be applied to any semantics, evident in the phrase "list of X". The preposition "of" makes it clear that this is a semantic extension of whatever kind of thing that X is. Furthermore, there is an obvious way to lift functions: just apply the function to each element of the list, and collect the results in a list. Bam! There's a functor. This is starting to feel like blog post territory, but I'll forge ahead...

An important point here is that the "semantic structure" that type constructors add to a basic type has to come from some extra data that is used when defining the type constructor. In the case of functors, we have to actually describe an algorithm that implements the lifted function in terms of its basic version (as we just did for lists).

So a monoid is also a type constructor, and it must come along with a description of the monoidal product: For type M, we need to describe a function (the monoidal product) which takes two A's and returns another A. We must also identify a specific value within type A that serves as the identity element. Now, to actually be a monoid, the monoidal product and identity element must satisfy some laws, but in general proving the laws are satisfied by a given constructor is outside of the capabilities of our type syntax. This is a step up from the functor type constructor, which needs only a valid implementation of the lifting function (called `fmap` in Haskell) in order to establish that we have actually created a functor.

In any case, to arrive at monads we don't actually combine the functor and monoid type constructors; instead we gently introduce monoid semantics on top of a functor. We do so by making the functor type constructor itself act like a monoidal product, so that repeated applications of the type constructor don't create "nested" versions of the semantics, they just stop at the first level instead. Lists are again a very straightforward example of this: List is a list of things of type A, and List> is a list of lists of As, and there is an obvious way to bring the list of lists back down to just a list: flatten it.

...okay maybe I'll stop there, at least for now.

Re: Monads are monoids in the category of endofunctors

#109
post #60
post #50

Earlier quoted context omitted.

> If you cannot communicate with a beginner in language they understand, A.) you don't really understand it either This is true, but the problem is that people will always prefer the explanation that is, as the saying goes, "simple, neat, and wrong" over the explanation that is more complicated, especially if they (and possibly the person explaining) aren't aware that the simplified version is wrong. Even if one star…

You have to start with the 'simplified but not technically perfectly correct' and then add in the nuances to get to the real point. Starting with words like 'functors' that most software engineers today will not be able to define is not useful.

The article is likely aimed at intermediate-ish FP programmers, though, not people with no prior knowledge. (Although I suspect it is an example of "learning by teaching", since it is wrong on many counts.)

Learn You a Haskell mentions functors in chapter 8 and teaches them properly in chapter 11.

http://learnyouahaskell.com/making-our-own-types-and-typecla...

Re: Monads are monoids in the category of endofunctors

#110
post #100

Earlier quoted context omitted.

And for those of us who struggle with rote memorization, it's a huge artificial barrier. Though in my experience even the "flash cards" are hard to find on the internet.

It's not an artificial barrier, you just didn't learn anything useful yet. So now you know what the words mean, but they mean super mundane stuff that you've probably dealt with a hundred times. You already knew how to use map and array concatenation before you even heard of the word monad. There's some magic to these words, but that magic is in how they're used to create new software, real things you can do with the…

I should be clear: you don't have to sell me on Haskell or these other concepts. I would love to add all that stuff to my toolbelt. I'm suggesting that the zoo of new terminology makes the effort barrier to doing so much higher than it needs to be.

I'm sure some of it really is warranted, but my experience looking at formal math and logic is that they make things a lot harder than they need to be by introducing terms and symbols that stand-in for intuitive concepts and require unnecessary mapping back and forth between what you're reading on the page and the underlying concepts.

Post reply on HN