
Please Don't Learn Category Theory (2013) - psibi
http://jozefg.bitbucket.org/posts/2013-10-14-please-dont-learn-cat-theory.html
======
jfarmer
The problem with being a programmer and learning category theory is two-fold.

First, category theory is very abstract. Indeed, mathematicians often jokingly
refer to category theory as "abstract nonsense." The story goes that Norman
Steenrod, one of the creators of category theory, coined this term himself.
So, category theory can be abstract _even for mathematicians_.

Second, the "stuff" that category theory was built to abstract is highly
mathematical and foreign to virtually every programmer who doesn't have a math
background. What's worse, the bits of category theory that Haskell uses most
frequently are typically _not_ the bits of category theory that mathematicians
use most frequently.

When you put these together, it's very hard to connect the dots between
"category theory", "category theory as Haskell uses it," and "Haskell as a
typical Haskell programmer uses it." To build up to the bits of category
theory that Haskell uses requires understanding things like categories,
morphisms, functors, adjoint functors, natural transformations, adjunctions,
and commutative diagrams, to name seven. Trying to understand these without
understanding their (inherently mathematical) motivations would be a tiny
nightmare — they'd feel like a bunch of disjoint facts and diagrams that are
supposed to mean who-knows-what.

And even if you get there, the categorial nature of monads in Haskell is not
exactly apparent on the surface. Haskell exposes more programmer-friendly
interfaces like "bind" that take some effort to translate into the language of
category theory.

A major motivator in the development of category theory, for example, was as a
tool to explore the relationship between topological spaces and groups, a
field of mathematics called _algebraic topology_
([http://en.wikipedia.org/wiki/Algebraic_topology](http://en.wikipedia.org/wiki/Algebraic_topology)).

~~~
drblast
I always feel like I'm at least seven or eight layers removed from anything I
can relate to when I read about category theory.

I'll think, "Hey, let me check this out on Wikipedia..." and I'm six linked
articles deep trying to understand the first paragraph of the original
article, and I'm no closer to anything concrete.

It's obvious at that point that the "top-down" approach is the wrong way to go
and that really the only way to develop an understand this is to take a class,
or buy a book that may or may not be more tractable than Wikipedia.

At that point, I'll consider that there are many other languages that are
supposedly esoteric that I've never had a problem grasping, and that I know of
few advantages that Haskell offers over, say, F#, for doing things I need to
do. And even though I've written some parsers in Haskell and it was a
generally nice experience, I just don't have time to learn category theory
from the ground up.

I also realize I really, really need to understand how my tools work from
cradle to grave or I'm deeply unsatisfied.

At that point I abandon Haskell as a curiosity and go on with the rest of my
life.

~~~
j2kun
If you're interested in more of a bottom-up approach, I have a series of
articles on my blog explaining category theory with the programmer's
perspective in mind (though I do assume you know a little bit of higher maths;
sets and functions, mostly). See the section titled "Computational Category
Theory" on this page: [http://jeremykun.com/main-
content/](http://jeremykun.com/main-content/)

I've let the series sort of fall to the wayside recently as I focused on other
content, but there's enough to get you up to a categorical understanding of
map, fold, and filter (and a mathematical justification for why fold is the
"most" universal one of the three)

~~~
drblast
Thanks, these articles are excellent. In particular, the first that explains
ML syntax in terms that I can relate to other languages _before_ you launch
into the concepts is great.

Almost every Haskell intro I've read tries to explain concepts in Haskell's
syntax. If the reader is unfamiliar with both, this is baffling.

------
tikhonj
A bit of a link-baity title. It's not that you _shouldn 't_ learn category
theory, it's that you don't _have_ to. Even if you want to program in Haskell.

But is it worth learning on its own? Probably. At least the basics are. You'll
get more insight into the design of languages like Haskell and ML and acquire
a bunch of new abstractions which have a very good "power-to-weight" ration:
that is, abstractions which are surprisingly general and expressive but also
simple. The compromise, of course, is that these abstractions are _really_
abstract--they do not admit good concrete explanations. At first, thinking
about this sort of abstraction is difficult, but they become extremely
powerful and convenient once you get used to them.

Category theory also helps people design libraries. In a sense, category
theory is focused on _composition_ , which is obviously integral to writing
good code. Additionally, some extremely useful constructs--like prisms from
the lens library--were discovered largely thanks to category theory.

Finally, category theory gives you a _new perspective_ on programming. I find
this very valuable because it gives me more than one way to think about
whatever I'm working on. It's useful in the same way Curry-Howard is useful--
in fact, there's a very natural extension of Curry-Howard to include
categories with certain structure.

So yeah: please don't feel you _have_ to learn category theory, but consider
learning it anyway.

~~~
joe_the_user
But the alternative he proposes actually sounds more daunting than learning
category theory: "In fact, try substituting

    
    
        Monad    -> FuzzyWuzzy
        Functor  -> Banana
        Category -> Cheerios"
    
    

Sure, uh, all the other languages I've learned involved using opaque labels
whose meaning I had to infer over time. No, that approach is for something
like esthetic theory. All the languages I've learned used pretty concrete
intuitive terms for their constructs, even the terms weren't really accurate.
Having to manipulate a construct without the slightest hint to qualities
sounds just maddening.

Learning a programming language is hard enough that I think the learner needs
terms that suggest they're dealing with something concrete even if they're
not.

~~~
axman6
Then try

    
    
        Monad -> Sequenced
        Functor -> Mapable
        Category -> ... I don't know, I don't use it much (not that it doesn't have a nice understandable alternative name, I just don't know it)
    

Monad and Functor are really quite simple classes to understand, and Tony
Morris' 20 intermediate exercises listed in the article helped me greatly when
trying to understand the concepts.

I've been a haskell programmer for 6 years, and feel I know about zero
cetrgory theory. It's never seemed to hurt me (except when Edward Kmett pipes
up in IRC and I don't understand a word after that =)

~~~
ekidd
For Monad, try "Flattenable". A monad is any type which:

1\. Supports map. 2\. Can be instantiated given a single value. 3\. Can be
"flattened" when nested two layers deep.

For example, an ordered list is a monad, because:

1\. You can map a function over a list. 2\. Given a value _x_ , you can
construct the list _[x]_. 3\. Given a list like _[[1,3], [2], [], [4,5]]_ ,
you can flatten it to be _[1,3,2,4,5]_.

There are a couple of other technical constraints, mostly related to what
happens when you (for example) take a list, stick into another list using rule
(2), and flatten it using rule (3), in which case you're supposed to get back
the original list. That sort of thing.

Monads are useful, and they appear everywhere—quite a lot of generic types
support "map" and "flatten". Haskell obscures this simple structure in two
unfortunate ways: (a) the first monad that everybody sees is IO, which is a
freakish outlier, and (b) Haskell uses an equivalent formation of monads based
on a function "bind", which is essentially a map (to a doubly nested type)
followed by a flatten.

Another way to look at monads is as "generalized list comprehensions" where
"list" can be replaced with hundreds of different clever things. It's a clever
little pattern that turns up everywhere, and when it does turn up, it tends to
be a sweet spot in the design space. A good recent example would be the
Promises/A+ spec for JavaScript, which is basically Haskell's Error monad.

~~~
aninhumer
I think the fact that two people suggesting this idea chose two completely
different names to replace "Monad" demonstrate pretty well why trying to use
an "intuitive" name is a bad idea.

I can just about get behind "Mappable" for Functor, but there simply isn't a
unifying notion that explains what a Monad is in one word. Some Monads are
better described by their join, and others are better described by their bind.
You call IO a "freakish outlier", but Reader, Writer and State all follow a
similar notion of sequence.

~~~
joe_the_user
_I think the fact that two people suggesting this idea chose two completely
different names to replace "Monad" demonstrate pretty well why trying to use
an "intuitive" name is a bad idea._

Uh so,

Because when you have a complex idea which can be approached multiple ways,
the best way to help people approach it is ... no way at all, no helping hands
or training wheels. See my other complaints about "we don't want to let you be
any bit OK until you have it all".

~~~
aninhumer
I'm not saying we can't use these words to help people understand, just that
we shouldn't rename core elements of the language just for the benefit of
beginners. Especially if the new names don't fit with half of their common use
cases.

Learning a new word is not what makes Monads hard.

------
rtfeldman
> the people who designed Haskell decided they weren’t going to pretend they
> didn’t use math

This is almost certainly the decision that has kept the most people from
successfully learning Haskell.

If you write "Appendable", many programmers go "oh, okay, got it." If you
write "Monoid", many programmers go "yeeeah, I don't know if I have time to
learn all this."

This is either a perfectly acceptable cost of avoiding redefining the wheel,
or a cautionary tale for future language developers, depending on your
perspective.

~~~
cscheid
But "Appendable" is a terrible way to describe what a monoid is. Some of the
really cool tricks in the way abstractions in Haskell match mathematical
notions come from extending the abstractions beyond what you would expect. For
example, integers under sum are monoids; naturals under the maximum operation
too. And so is the "over" operator from computer graphics. All of these find
applicability as general monoids in Haskell, but you'd have a hard time
calling them "Appendable". All of these just need a binary operation that's
associative and with an identity element.

The same thing happens for functors and monads: their use come from the
properties they respect. And if you accept that abstractions will be defined
as a set, some operations, and some algebraic laws respected by those
operations, well, then, you arrived at abstract algebra, and you might as well
use the right terms.

~~~
yohanatan
I think Combinable is more appropriate as 'append' pertains to only one of
many associative binary operations.

~~~
cscheid
What about a group? Is that combinable too? Monoid is short, precise, and
googlable. Which also happens to be the case with group, monad, functor, etc.
Why invent new vocabulary?

Have you noticed how little sense the words "class", "struct", "union",
"object" make to someone who hasn't programmed before? It's just that we got
used to them.

~~~
lmm
Classes, unions and objects are all everyday words. I knew them from
mathematics and everyday life before I ever used them in programming.

------
saosebastiao
I call mega-exponential-factorial-to-the-n-bullshit. I tried doing exactly
that. You can't learn Haskell beyond superficial hello world apps without
learning what a monad or functor are, because there aren't any substantial
teaching materials that don't force you to understand it in order to continue
learning, and all the common libraries require you to know how to use them
because they are undocumented and have no examples.

Can you use Haskell without understanding how those things work? Sure...if by
"use" you mean you are limited to copied and pasted code snippets without an
ability to understand what your code is doing, with the slightest change
causing unintelligible compile errors.

~~~
nilkn
My impression of the article was not that you don't need to know what monads
and functors are, but rather that you don't need to understand them on the
level of category theory. I think that's a true statement, if your interest is
in simply writing software in Haskell and not in breaking new ground in the
Haskell community (like writing the lens library itself).

------
ekidd
This is a nice, short article which basically says, "You don't actually need
to go learn a bunch of category theory if you want to learn Haskell, so please
don't stress about it." Despite the title, it's not any kind of general
argument that no programmer should learn category theory.

Category theory is a strange branch of math—it's almost entirely definitions,
with only a handful of interesting theorems. As far as I've been able to
understand, category theory is a very abstract analogy between very different
branches of math: abstract algebra, topology, mathematical logic and (here's
the interesting part) the lambda calculus, via Cartesian closed categories.

This analogy has interesting payoffs, especially for programming language
designers and people trying to do seriously weird stuff. For example, let's
imagine you have a value of type A, a function from type A to type B, and
another function from B to C. But if you squint at these types right, it's the
same as a logical system where A is given, A implies B, and B implies C. Now,
it turns out we have automated theorem proving software that can take
statements like this and figure out how to get from A to C (even in much more
complicated situations). And it turns out the analogy between types and logic
is sufficiently strong that you can actually use a theorem prover to write
certain kinds of programs without any human intervention, given nothing but
the type signatures of your functions.

And this is not the only clever analogy lurking here: My favorite is the way
that probability distributions can be mapped onto the lambda calculus.

So, no, you don't need to know all this math to write Haskell programs.
(Although some library authors are a little nuts, generally in a good way.)
And yes, category theory is a weird branch of scarily-abstract math without
many theorems, and Haskell only uses certain corners of category theory.
Still, there are times when category theory will allow you to see how far-
flung branches of math can be mapped tidily onto the lambda calculus. And that
should be of interest to Lisp developers, at least.

------
lmm
You need the words to be able to use Haskell. There are too many of them to
learn otherwise. I have a similar experience with scalaz, where I tend to only
spot useful things in the library after I've reimplemented them, because they
don't have names that let me find them based on what they do.

(Possibly the only benefit of a previous company that wouldn't let me use
scalaz was that, in reimplementing it myself, I got to give the typeclasses
sensible names like "CanFlatMap")

------
bonemachine
Finally someone has the courage to tell the Truth about CT.

Next up: the idea that the notions of Monad, Functor, and Category (in
whatever guise) are even needed or helpful to do strong FP.

~~~
cnlwsu
I was able to be fairly effective (imho) in clojure/scala without knowing
anything about fuzzyWuzzies, bananas, and cheerios. I felt learning about them
becomes interesting though as you dig into the language more. Mostly as a
curiosity thing... spend some time to "finally learn about monads" to see
you've been using them the entire time.

------
badman_ting
Makes sense if your goal is to use some particular language (in this case
Haskell). But a lot of us don't necessarily need yet another programming
language, whereas adding to our theoretical knowledge can be beneficial no
matter what environment we're programming in.

------
rschmitty
Side note from this submission is that I did learned you can host html like
github

[https://confluence.atlassian.com/display/BITBUCKET/Publishin...](https://confluence.atlassian.com/display/BITBUCKET/Publishing+a+Website+on+Bitbucket)

Nifty!

------
orlandob
Linkbait trash.

"Don't do this thing everybody says you should do. But I do and I like it."

~~~
Aqwis
That's a very dishonest summary of the article. What he's actually saying is
this:

"Don't do this thing everybody says you should do, except if you're _actually_
interested in the math."

~~~
andrewflnr
Then he really should have titled it, "You don't need to learn category
theory", not the imperative "don't...". As it is, this is a textbook case of
linkbait: choosing a dramatic title to get clicks.

------
guard-of-terra
With such a great number of people around me dabbling in Category Theory, I'm
not sure it's worthwhile anyway. I don't like crowded areas. Maybe learn
something useful but less hot - cryptography perhaps?

~~~
KirinDave
Are you too cool for category theory?

Fashion is a terrible reason to learn math, or to decide against learning it.
Don't be a hipster.

