Streaming studying category theory on Twitch today.
- Yapping notes
- I'm going to stop reading Category Theory Illustrated by Jencel P because I'm frustrated with it, and I think I need to read more material about it.
- Talking about how I would teach programming
- I would start with defining, philosophically,
what computation is exactly and the different ways
of doing it:
- The typical understanding of computation is to do binary (boolean logic), but this isn't the only way.
- For example, computation in lambda calculus can be represented with a diagram: https://www.youtube.com/watch?v=RcVA8Nj6HEo
- There's also the HVM, which uses interaction combinators to do computation in parallel https://higherorderco.com/
- Analog computing and chips that can do matrix multiplication cheaper: https://www.youtube.com/watch?v=GVsUOuSjvcg
- I would start with defining, philosophically,
what computation is exactly and the different ways
of doing it:
- Talked about the Oyasumi Punpun quote that starts with "Let me guess, you still think you have time..." https://www.youtube.com/watch?v=P07rqHQ35hU
- We're going to read Category Theory for Programmers by Bartosz Milewski today, based on the recommendation from 20251002175833. It's available on his blog here.
- Preface
- Author mentions reading Saunders Mac Lane’s Category Theory for the Working Mathematician, which was also recommended to me in a previous stream I think.
- While they are going to do C++ examples, I'm so happy that they recognize some of the reason for why C++ sucks
- They present the argument that functional programming is the future of language design and that all languages will move to it because of multicore processing. I don't really agree with this, since I think functional programming features finding their way into imperative languages is more due to their maintainability and ability to reduce the complexity of code than it is about everything becoming multicore. However, I do find their point of how locks don't compose valid and interesting.
- They continue to point out that aside from concurrency, that side effects are really hard to deal with, which I agree with.
- Part
1, Section 1 - Category: The Essence
of Composition
- Categories are defined in this book as a set of objects and arrows that go between those objects.
- Arrows are also called morphisms. Arrows can be thought of as functions, which take an argument of one type and returns a result in another type.
- Arrows can be composed with each other such as in g ⋅ f
- They mention that you cannot check the equality of functions, which is too bad because I think that would be really neat. I've been thinking about making a programming language where you could inspect its own abstract syntax tree, and this might be a thing that would be possible in such a scenario.
- Categories have to follow two properties:
- Composition has to be associative
- For every object A, there is a unit of composition, which is an arrow that loops from the object back to itself.
- We need the identity function because it's
useful when working with symbolic variables in the
same way the number zero is useful.
- The identity function can be used as an argument to or a return from a higher-order function.
- Higher-order functions make the symbolic manipulation of functions possible.
- "Higher order functions are what make symbolic manipulation of functions possible. They are the algebra of functions."
- I'm getting called out!!! I started the stream by asking "What IS computation" and the guy is literally saying "Functional programmers have a peculiar way of approaching problems. They start by asking very Zen-like questions. For instance, when designing an interactive program, they would ask: What is interaction? When implementing Conway’s Game of Life, they would probably ponder about the meaning of life. In this spirit, I’m going to ask: What is programming?"
- "Category theory is extreme in the sense that it
actively discourages us from looking inside the
objects. An object in category theory is an abstract
nebulous entity [...] The moment you have to dig
into the implementation of the object in order to
understand how to compose it with other objects,
you've lost the advantages of your programming
paradigm."
- I think it's very enlightened to understand category theory this way. My struggle with learning category theory is that there's a lot of abstractness and lack of concrete examples, and that ends up confusing me. However, pointing out that not knowing what the object is as an intentionally good part of category theory, and that i should focus more on how the composition of objects work is really appreciated by me.
Part 1 challenges:
Fuck, I can't use Haskell. They called me out again!!! What is my second-favorite language??? I feel like if I say Purescript I'm cheating because it's basically Haskell. I hate C#, but I like it more than GDScript. I guess it's Rust :T
fn id<T>(a: T) -> T { return a; }While looking up how to do polymorphic functions in Rust, I found a page that provided an example with a
traitcalledGrowlerwhich reminded me of this Internet Comment Etiquette video where "growler" is used in a way that sounds dirty, which in turn caused me to wonder what a "growler" even is.Apparently, a growler is a glass that beer is stored in. While reading about it here, I noticed that they mentioned that "64-ounce amber glass growlers protect your beer from UV light". I didn't realize that UV light affects the taste of beer, so I wanted to know what this was about. Apparently, UV light can change the taste of beer by converting the hop chemicals into 3-methyl-2-butene-1-thiol which is reminiscent of a skunk spray,
making it known as "skunked beer".Cans are still affected by this phenomenon, I'm assuming because UV light can still penetrate the can, and I wonder if this is at least one of the reasons for why I have always thought that canned beer is bad.
The topic of jug playing came up, apparently all the jug does is amplify the sound coming out of the musician's lips, so all you need to do to change pitch is to change the sound made with your lips.
This one seems easy enough, in Rust:
fn compose<A, B, C>(g: fn(B) -> C, f: fn(A) -> B, a: A) -> C { return g(f(a)) }I think we just need to try using compose with id on either side of the function. This...
fn main() { println!("{}", compose(id, id, "Hello, world!")); println!("{}", compose(id, int_to_string, 4)); println!("{}", compose(int_to_string, id, 4)); println!("{}", compose(id, int_to_string, 4) == compose(int_to_string, id, 4)); } fn id<T>(a: T) -> T { return a; } fn compose<A, B, C>(g: fn(B) -> C, f: fn(A) -> B, a: A) -> C { return g(f(a)); } fn int_to_string(a: i32) -> String { return a.to_string() }...prints out this:
Hello, world! 4 4 trueI think the world-wide web is a category, because you can think of the links as arrows which take you from one page to another, and combining arrows together gives you a direct connection from the first page to the last page.
I don't think Facebook is a category, because just because i'm friends with a person and that person is friends with someone else, that doesn't mean i'm friends with my friend's friend. That means friendships cannot be morphisms -- they do not compose.
I think a directed graph is a category when each node has an arrow pointing back to itself, as that is one of the requirements for composition in a category.
In the comments, the author points out that there are no right or wrong answers to the challenge questions and that they are just food for thought.