I think it does. Of course, I think this as somebody who has just begun learning about it, so I certainly don't speak from any experience :P.
Particularly, category theory seems to center around abstraction. I think abstraction is essentially the core of CS (but maybe that's just because of SICP) and exceptionally important in everyday programming. Learning this sort of math (along with some related fields like abstract algebra) essentially allows you to unlock a higher level of abstraction.
This can help in two ways. For one, it allows you to write more general code and create extremely useful libraries. The Haskell standard library, naturally, is a great example of this. Additionally, it helps with thinking about conceptually difficult concepts in programming. For example, even just the basic ideas of category theory really helped me to understand and work with non-deterministic programming. Thinking about composing non-deterministic functions, and how these functions behave much like normal functions, made life much easier.
Category theory is one of the more abstract branches of math, so it's no surprise that it lends itself to great programming abstractions. Understanding and using such abstractions in a uniform and systematic way is extremely useful, so I think it's definitely an area that would be beneficial for programmers to study.
It's also fun, but that's another story entirely :).
I think all programmers should learn one of the more abstract maths, like abstract algebra or real analysis. Like you say, it helps train in abstraction. However, I'm less than convinced that Category Theory is a good choice compared to other branches of math.
This may be a mathematician's bias, but Category Theory is somewhat underwhelming because you can't really do anything with it. It's actually too abstract--you can model basically every branch of mathematics with Categories, but you can't actually prove very much about them from this perspective. All you get is a different vocabulary to talk about results that you already knew. It's also less approachable because its objects of study are other branches of mathematics, whereas most other branches have number, vectors, and functions as standard objects.
Abstract Algebra, Real Analysis, and Set Theory will provide you with very similar experience with heavy abstraction, while also teaching some specific tools that are more practical. Abstract Algebra is the beating heart of Fourier Transforms and crypto algorithms, as well as a similar experience with data transformations that you would get from Category; Real Analysis gives a lot of numerical algorithms, stability, and a good handle on dealing with unbounded scaling; Set Theory is relational databases, data representation, and again with the data transformations. Category Theory gives you Monads... which are actually pretty cool, but I honestly found Category Theory more of a hindrance than help in figuring how they work.
tl;dr Every programmer should learn math for the abstraction. Category Theory is pretty good for this, but other maths might be better because Category Theorists are the Architecture Astronauts of the math world.
>This may be a mathematician's bias, but Category Theory is somewhat underwhelming because you can't really do anything with it. It's actually too abstract
It seems Category Theory might one day be useful in ordering "Upper Level Ontologies". Since it's logically impossible to have one consistent ontology( Incompleteness Theorem ) the next best thing is to find morphisms across knowledge domains, no?
""The amount of information out there is growing exponentially. The amount that needs to be known before you can contribute keeps exploding with each generation. Such that the practitioner might know just as much if not more than their predecessors but the scope of their knowledge as a fraction of the full body is many orders of magnitude smaller.
It is not just a matter of will but of physics of time and the chemistry of the brain. Underutilized connections fade such that unless you spent time actively practising the wide skill sets to sufficient depth they will fade. But there is not enough time to be able to do that.
I do think that more must be done in enabling bridges as a counter to this. It is a shame category theorist must wrap their material in such obtuse language as it seems that it would be just the tool for the job.""
What exactly would be the benefit of using category theory? What would you gain in comparison to doing just normal homomorphisms? And that's even assuming you would be able to find a homomorphism at all; it may well be prevented by the ontologies being mutually inconsistent, right?
The benefit is its flaw. Because it is so abstract it is able to describe many, many things. It can serve as a basis for all of maths and unlike set theory really focuses on structure. Very roughly, think of it like functional programming to Set theory's imperative nature.
It is not a tight analogy. But: In set theory you pay a lot of attention to the internals of collections of objects. In category theory you are more interested in capturing structure and relationships.
In imperative programming you specify the internal sequence that makes up an operation, in functional programming you are more interested in the high level declarations, compositions and that the constraints on them are satisfied.
That was very much the goal of "Systems Theory"[1]. The problem is it's focused on "natural systems" with quantitative relationships. The work has fallen short in capturing phenomenological relationships.
I think Wilber's AQAL ontology comes closest to being the most "well defined"[2] but also a little whacky. The cornerstone of the model is differentiation across pronouns. The assertion is perspectives are partitioned across 1st, 2nd, and 3rd person perspectives. So for example, art, ethics, and "truth" are the broad knowledge domains. He takes this further by then saying you can take a 1st/2nd/3rd person perspective on actual 1st/2nd/3rd persons.
The value I got from my abstract algebra course is the ability to identify things that are identical, or at least similar. A big part of abstract 1 is just manipulating symbols to appear in a form that's usable with a provided theorem.
I was learning Haskell for last six months (part of my undergraduate studies).
It was (and is!) fun and challenging but I had hard time seeing any measurable profits from learning what are and how to use functors, monads etc.
Until recently when I was writing asynchronous communication framework in Python and I was searching for simple solution to sequence actions in this heavily callback-based environment.
Now everything looks so simple... (I am looking at you, monads!)
The bad part is that many people do not know what I am talking about when I try to describe them the design ;)
I had the exact same experience! A light went off when I figured out how to elegantly sequence asynchronous calls in Scala, and it was then that I realized I was using Monads to do so.
However, I am curious if python's solution looks ugly (since they don't seem to have a 'do' or 'for' expression that Haskell and Scala have respectively)?
I did the same thing in Ruby [1], but it does indeed look uglier than the equivalent Haskell/Scala because of the lack of language support for monadic syntax.
The benefit of realising the monadic behaviour of asynchronous sequencing (which I call "Deferrable#bind!") was that if you had a bunch of nested callbacks, the monad associativity law [2] meant you could replace them with a simple linear sequence of chained bind! calls:
fetch().bind! do |a|
process(a)
end.bind! do |b|
process(b)
end.bind! do |c|
# ...
end
instead of
fetch().callback do |a|
process(a).callback do |b|
process(b).callback do |c|
# ...
end
end
end
I find the former a lot more readable, partly because the "end" keywords don't all pile up at the end, and especially if you try and do error handling (in the nested case the error handling ends up in reverse order!).
I'm guessing you can't really do a 1:1, although maybe the OP can clarify.
They do stuff like this in jQuery, so I can't imagine it's all that difficult in Python.
My initial thought would be to write something analogous to Maybe. You can't pattern match in Python, which is a shame, but you could make it so that foo.bar().baz().quux() will return MaybeResult, which everything involved in the transaction inherits from. MaybeResult might have a "success" variable on it indicating whether it ought to be treated as Nothing. Otherwise, check "result."
This is naive but it gets you a little bit closer to fault-tolerant chaining of interdependent methods. Not as nice as Haskell, obvs. :)
I actually had a very similar revelation in JavaScript. Using Haskell-style arrows to abstract over things like events and CPS functions is really great for that sort of code.
The real beauty of these concepts is that they are not tied to just one logical thing. They're applicable to callbacks and networking, but then they translate effortlessly to handling errors or early termination or non-determinism.
I am hard pressed to find any practical use for Category theory. No that is not quite true. Knowing concepts like the fusion law, natural polymorphisms, initial and final algebras, ana/cata/hylo morphisms make many fuzzy patterns concrete. And motivate many algorithms. But I have never found a use where a theorem was useful in deriving some part of a program. I feel it helps my programming the way some people say Lisp helps their Java. But I have flipped through Bird's Algebra of Programming a very few times to solve some problems.
In my experience, programmers who try to "think generically" tend to write overly abstract code that just gets them into trouble and leaves a mess for the next programmer. So maybe knowing category theory makes you a worse programmer?
It seems like this question would be more convincingly answered by showing how a practical program can be improved by knowing some category theory.
> In my experience, programmers who try to "think generically" tend to write overly abstract code that just gets them into trouble and leaves a mess for the next programmer.
Amen to that. I think part of what makes a programmer "good" is knowing where to draw the line between flexibility and maintainability. Personally, I start with very little abstract code, and only "blow it out" into abstraction when the flexibility is demanded by other code/interfaces. The trick to managing this kind of style is to never say "no" (barring special circumstances) when flexibility/abstraction is required, so you're rarely writing kludges, and to always say "yes" when you realize that some abstractions have consolidated and can be de-abstracted, so you're rarely leaving cruft.
I think that might be a language-dependent phenomenon. Most mainstream languages aren't suited to building useful abstractions. But we might all be talking past each other without examples.
I think the opposite is true: more abstract code is easier to maintain. Why? Because the abstractions constrain what you can do in well-defined ways. Code for your particular domain tends to be somewhat undefined. What sorts of behaviors should you allow? What sorts shouldn't you allow? The answers are going to differ with each domain.
On the other hand, these questions are very well defined for mathematical concepts. If all you know is that you're operating on a functor or on a monad, the possible behavior you can rely on is based on concrete mathematical laws. As a simple example, take lists. If you just treat lists as lists, there are all sorts of possible problems you can run into: off-by-one errors, not accounting for empty lists and so on. If you write code across all functors, on the other hand, you cannot make any of those errors.
Essentially, abstraction like this lets you concentrate all the possible errors in a very small portion of your code. You can write the abstract code assuming that the functor laws or the monad laws or whatever applicable laws hold. Moreover, since the code is polymorphic, the type system guarantees that you cannot do anything not provided by the abstraction you chose. Code that does something beyond the abstraction is simply not well-formed--it relies on properties of the type you simply cannot access.
This means that all your code will be valid given that the type behaves like a proper functor or monad or whatever. Now the only code you have to test for your particular domain is the functor or monad instance. Once you prove that your monad instance follows the monad laws--which really isn't very difficult in most cases--you know that all your abstract code also works for this particular domain. So now the only place you can have an error in is the code making your type an instance of some type class. This should be much easier to maintain than having a bunch of ad-hoc code for each particular domain!
In short: more abstract code is easier to maintain because it restricts the programs you can write. If you rely on as little knowledge about your particular domain as possible, you will have far fewer places to make a mistake. Mathematical abstractions are particularly good because they tend to be far better defined and understood than purely programming abstractions. Something like Iterable doesn't have the sort of mathematical laws that classes like Functor and Monad do.
I'll agree that if you have an important invariant then it's nice if the compiler can check it. But the question to ask is: where did these constraints come from? How do you know they're true? What if they change?
If they're business requirements: can you undo them if the business changes? If they're environmental constraints: do you really know mobile phones or browsers or the server OS that well, and what do you do when a new version of the environment comes out and invalidates your assumptions?
Generally speaking, it seems better to take our inspiration from scientists doing empirical work, rather than from mathematicians. Use tests to figure out how the code you depend on really behaves, not how you wish it would behave.
Agree. The urge to over-abstract systems seems to stem from the same human tendency to see patterns where none exist. In the latter, we ascribe hidden structure, in the former, we create hidden structure.
This is a very well written post and I have a great deal of respect for its author. I also happen to find Category Theory to be extremely beautiful, but its beauty (much as the beauty of many other theories in physics and mathematics) does not rest upon its applicability to programming.
The ultimate answer to the question is more nuanced: understanding functors and monads is probably only moderately correlated with programming skill and not just in an enterprise software context (would it be of any use to an embedded programmer or a kernel hacker?). Additionally, using and applying a limited subset of category theory in practical context (lifting, functors, monads) does not really require understanding category theory per-se, although I'd imagine it's a good "gateway drug" (learning Haskell had this effect on me).
Yes. It can also make you a better topologist, physicist and logician, as this paper states it[1]: Physics, Topology, Logic and Computation: A Rosetta Stone
This paper is also a very good introduction to Category Theory.
You don't need Category Theory to tell you that there is a duality between structs and unions, any C programmer could tell you that.
Mind you I spent a lot of time working with Haskell in an academic environment and never understood the first thing about category theory. Especially those bloody diagrams that were supposed to be proofs.
It is entirely possible to understand functional programming and abstraction without understanding any category theory...
I disagree. I think that if you understand functional programming and abstraction, you understand a certain amount of Category Theory even if you don't know to call it "Category Theory".
That's bait and switch. The question is whether people should study category theory to be better programmers. Not whether good programmers have intuitively mastered some category theory.
Not any C programmer could give an explicit, formal definition of "duality" and show how it applies to structs and unions. So yes, you do need category theory for that.
How do you know that it's entirely possible to understand functional programming without understanding category theory, when, by your own admission, you "never understood the first thing" about it?
What I mean is that it is objectively difficult to know that you understand A. How do you know that understanding B wouldn't give you a greater understanding of A?
If he'd claimed "I understand CT and it didn't help my understanding of FP in the slightest", I'd have no qualms. The problem I have is, what he's saying is essentially "I don't understand CT, but I'm having no problems with FP without it".
Here's an analogy. There's an apprentice carpenter who has been given some tools and as far as he is concerned the tools he has been given are all of the tools in existence. It's quite clear that if he was given a new tool, he could immediately establish whether it was useful or not. He could not establish, however, that he has access to every useful tool.
From his account, I don't know whether CT is like a hammer that he is using upside-down (needs explanation before it's useful) or a banana (never going to be useful to construct anything).
>what he's saying is essentially "I don't understand CT, but I'm having no problems with FP without it."
Saying that understanding category theory can give you a greater understanding of functional programming doesn't imply that a lack of understanding of category will cause problems in the understanding of functional programming.
Our difference is that I do not see anything in the thread parent that contradicts the article, and I don't think he's trying to convince you that CT is either a hammer or a banana, just that professional carpentry work is possible without it.
Every new way that you can impose a schema on the world helps you as a programmer, as long as you know that it is just another way of looking at things.
One of my CS teachers is very bold on saying that understanding program calculation can increase the quality of code, though he fails completely to help his students apply the knowledge he "preaches".
Anyway is a very intelligent guy(genius like), and is making a book on the subject (still incomplete). Here's the link if you're interested: http://wiki.di.uminho.pt/twiki/pub/Education/CP0809/Material...
My teacher does bring up interesting points, such as the lack of programming quality these days, and the lack of precision in what should be very precise and defined, namely "software engineering".
It seems like you get most of this stuff from a basic abstract algebra course. How does category theory help me beyond what I got from modern algebra 101?
edit: this is from the perspective of someone who knows a little abstract algebra, and wonders if it would be sufficient to brush up on my algebra to get these ideas, which seem a little familiar, or if category theory is really important to get these ideas. I'm not trying to be a contrarian.
Although some aspects of Category Theory will apply to Programming, it seems to me to be a slight abuse of language in that the majority of the theory does not correspond to physical and/or digital systems.
More importantly, Category Theory is a language that allows you to describe behavior and qualities, abstractly; it does not prescribe a specific methodology.
Do any of the following awesome programmers know and purposefully use category theory:
- Linus Torvalds
- Joshua Bloch
- Fabrice Bellard
- John Carmack
- Alan Kay
- Peter Norvig
- Paul Graham
- Rich Hickey
If not, then I think there are many different things that would make you a better programmer, before learning category theory is worthwhile to learn.
Let's also ask the reverse question: name an awesome programmer, preferably with an open source example of his code, that knows and uses category theory.
Calculus didn't exist in their time, so it couldn't be used by them. Moreover, much progress has been made in science, partly due to calculus. In fact, an awesome scientist today is much more powerful than an awesome scientist back then.
Can you show examples of practical progress made in computer science due to category theory? A bugfree web server, a secure web browser, an OS perhaps?
I was refuting a claim of a necessary condition by showing numerous counterexamples. In case of your crazy belief, coming up with such a list would be an attempt to prove a necessary condition by showing numerous examples. That is not logically valid. A list of counterexamples is.
this is a bit of a stretch in that the concepts used in category theory are surely useful to programmers, but in reality programming is often sufficiently complex that category theory is too general to apply. you can spend all day drawing diagrams about morphisms, direct products, pullbacks, etc but the real work is in coding the api, not drawing pretty pictures.
most programmers don't have the time or inclination to complete an undergraduate degree in mathematics, which is essentially a prerequisite for taking a legit category theory course. category theory is usually taught at the graduate level.
category theory definitely helps in theoretical physics :)
Particularly, category theory seems to center around abstraction. I think abstraction is essentially the core of CS (but maybe that's just because of SICP) and exceptionally important in everyday programming. Learning this sort of math (along with some related fields like abstract algebra) essentially allows you to unlock a higher level of abstraction.
This can help in two ways. For one, it allows you to write more general code and create extremely useful libraries. The Haskell standard library, naturally, is a great example of this. Additionally, it helps with thinking about conceptually difficult concepts in programming. For example, even just the basic ideas of category theory really helped me to understand and work with non-deterministic programming. Thinking about composing non-deterministic functions, and how these functions behave much like normal functions, made life much easier.
Category theory is one of the more abstract branches of math, so it's no surprise that it lends itself to great programming abstractions. Understanding and using such abstractions in a uniform and systematic way is extremely useful, so I think it's definitely an area that would be beneficial for programmers to study.
It's also fun, but that's another story entirely :).