{"url": "https://www.youtube.com/watch?v=uwkahlDlhHc", "page_url": "https://www.youtube.com/watch?v=uwkahlDlhHc", "title": "Monki Gras 2014 Greg Brockman on Building better software through mathematics", "show_or_channel": "James Governor", "date": "2014-03-05", "duration_s": 1029, "type": "talk", "speakers": ["Greg Brockman"], "confidence": "high", "notes": "Monki Gras 2014 (London) talk as Stripe CTO.", "people": ["greg-brockman"], "id": "2014-03-05_james-governor-monki-gras-2014-greg-brockman-on-buildin", "audio_duration_s": 1029.4335, "worker": "jc-w05", "transcribe_s": 12.6, "model": "large-v3", "segments": [{"start": 7.38, "end": 30.22, "text": "TLDR there was, been thinking about this for a long time. Back in the day, I did a bunch of math stuff. That I was really into math competitions and started doing a bunch of math research and publishing math papers and really was going down that road. And in the course of this, that I met a bunch of really awesome math people. You know, some of the best mathematicians my age in the world."}, {"start": 30.22, "end": 59.23, "text": "When I went off to college, I was really excited to finally be at the same school as all these awesome mathematicians. And so I showed up at Harvard and found that all of these great mathematicians were just no longer doing math, that at least 50% of those people had switched into computer science. And not just computer science, but actually software engineering, really getting their hands dirty with building things. And the really fascinating thing was these people who were just amazing at math were also really amazing at..."}, {"start": 59.23, "end": 80.86, "text": "Building things. And at first glance, this made no sense. Like, what's the correlation there? Are these just people who are amazing at everything? I mean, that's possible. But as I started to get more and more into computers, I realized that at first, computers were all about syntax. It's all about churning out some code that actually works, and that that takes all of your mental effort."}, {"start": 80.86, "end": 106.94, "text": "As soon as you get a handle on that, as soon as you get some fluency with actually producing code, you realize that there's a lot more to building a system than that layer. Really, building a system is about abstraction. It's about figuring out how should this thing work. It's about taking a problem, decomposing it into pieces, and trying to build something out of that. And at the end of the day, that's exactly what you do when you're doing mathematics."}, {"start": 106.94, "end": 132.53, "text": "And so I think that my fundamental claim here is that mathematical problem solving is sort of parallel to everything that you do in software engineering. And so if you understand mathematical problem solving very well, then that'll give you a lot of insights into how to actually build software. And so a good example here is to pick kind of an arbitrary problem in math, determinants."}, {"start": 132.53, "end": 155.81, "text": "And so you might remember these from your math classes, that determinants are some function on a matrix that tell you some interesting things about that matrix. And there are kind of three ways that you can go about defining a determinant. The first thing, which is sort of the plug-and-chug method of mathematics, is that you sort of define this as like, here's some function, here's some variables, and then you have to go out and brute force everything that you want to prove there."}, {"start": 155.81, "end": 181.04, "text": "You know, it works, but oh god is it painful, and doesn't really tell you anything interesting about why this is true. And that the parallel in engineering is this is just the same thing as just bang code into your editor, if it works, great, that's all that matters. Again, you don't really understand why it works, that there's nothing really deep there, it's just like, you know, this collection of symbols happens to be something that translates into a correct result."}, {"start": 181.17, "end": 208.59, "text": "And if you think about this in code, here's how this looks. It's just straight line code. The example that I'm using here is just implementing the card game of war. Now, in math world, you can take things to another level of abstraction and think about it in a little bit deeper of a way. And so for determinants, you can actually instead flip it on its head, and you can define them as just some function that has certain properties that are interesting. And then given that,"}, {"start": 208.59, "end": 231.2, "text": "All of the symbolic manipulation that you did before just sort of falls out. You don't really have to do it just because you can prove some properties and get everything from this abstract existence. And so this is a pretty clever way of approaching it. And it turns out that there's something that feels very similar to this on the engineering side, which is you have a problem, and rather than just splatting code into your editor, you think about..."}, {"start": 231.2, "end": 258.35, "text": "What actually are the components of this problem? Break it apart into modules. Those modules should have very clear implementations. And suddenly, this problem that was very complex and that was going to require you just to sort of write all this code has suddenly become a bunch of very small, individually easy subproblems. And here's what this looks like in code, just like standard object orientation. You have a card. You have a hand. You have a game. And you just sort of thread all these things together. It's pretty natural. It feels right."}, {"start": 259.54, "end": 288.93, "text": "Now, it turns out that you can do even one step better than that. And so, in the mathematics world, you can actually go and define this whole theory of exterior product spaces. And this is the kind of thing that takes a decent amount of work to really figure out even that this is a direction worth going, and it's incredibly abstract, and it's not the kind of thing that most people are exposed to. But the really interesting piece about this..."}, {"start": 288.93, "end": 312.38, "text": "is that as soon as you've done that theory, the determinant falls out as a special case. And suddenly this thing that you've been trying to get your hands on, that you've tried to do symbolic manipulation, you've tried to do these other things, suddenly it's very obvious what all these properties are because this is a special case of this very general theory. And the thing about this kind of approach to problem solving, where you first generalize to this crazy abstract..."}, {"start": 312.38, "end": 339.06, "text": "And then you solve your problem as a special case. It solves not just your specific problem, it also tells you at a very fundamental way why is your problem true. And it also solves all similar problems forever and ever, which is why I refer to it as the ender's game approach to problem solving. And so on the engineering side, there's a pretty close parallel, which is if you have a problem,"}, {"start": 339.06, "end": 366.78, "text": "That if you can figure out what is the real fundamental essence of this problem. And not just decompose it into modules and go and do that, but really it's the, okay, so decompose it into modules, and then what is a general form of this module? What does that look like? And then go and implement that. It turns out doing this is really, really hard. You need to understand your problem domain at a very intuitive level. And so when we're building systems at Stripe, that we don't try to do this up front."}, {"start": 366.78, "end": 393.62, "text": "We usually wait for at least three or four different use cases of similar related functionality, and then figure out, OK, now that we understand the space of possibilities, how can we take all this code that's different, refactor it into one coherent piece, and end up with a library that works in general? And the kind of thing that I'm thinking about here is if you just define some generalized card game class, and then you can have specializations of that that"}, {"start": 393.62, "end": 420.62, "text": "Or you can specialize it slightly differently and end up with Blackjack or something like that. And that writing something like this is really hard because you have to understand all possible things that are interesting about card games in sort of the space of card games that you want to be able to model. And at the end of the day, I think that the real reason that math and software are so similar is that math really is just programming."}, {"start": 420.62, "end": 448.74, "text": "You have this incredibly expressive language, which we call English. And it's super performant because you just don't worry about execution speed at all. If you have a theorem and you have a proof for it, you can just layer on top of that without thinking about what the runtime looks like. And sort of said another way, math is a discipline where you sort of don't have to worry about the details of actually getting something to run. And this is powerful in some ways."}, {"start": 448.74, "end": 470.27, "text": "Because it means you can really focus on the core of how do I model a system? How do I think about how this thing should work? What is fundamentally the case about whatever it is I'm trying to express? And of course, it's limiting in other ways because it means that this thing only exists in your head. It can't actually exist in the real world."}, {"start": 470.27, "end": 496.9, "text": "The way that I like to think about this is mathematics is like free climbing. It's like scaling up this cliff, and you have no equipment, nothing holding you up there. And software engineering, on the other hand, you have all this nice tooling that you have. Rather than having to fit everything in your head, you have a compiler, maybe an interpreter. You have the ability to actually execute your code against real data. And so if there's something that you're not sure about,"}, {"start": 496.9, "end": 521.78, "text": "Rather than having to execute in your head as you would in mathematics, you actually could just sort of shell out to this compiler. And so I guess that the point that I've been trying to make there is that there are parallels, that at the end of the day, mathematics and software engineering feel very, very similar, that when you're solving problems in one, that you're actually solving problems in the other. And the real..."}, {"start": 521.78, "end": 548.74, "text": "The time that this is interesting is if it can't just tell us, OK, here are things we already know, can it tell us things that we haven't quite understood or haven't been able to put our finger on and actually help us build better software? And my answer to that, as you might imagine, is yes. And I'm going to present a few examples. So one example of this is in mathematics that there's a very well-defined notion of elegance."}, {"start": 548.74, "end": 578.7, "text": "And it's sort of a, I know it when I see it kind of thing, that any mathematician will sort of look at a proof and tell you, is this thing elegant or not? And they might not be able to write down a definition, but it's something that does just permeate the culture. And there's something about simplicity there, that whatever is elegant is something that has no unnecessary work, that there's nothing there that isn't natural, that doesn't need to be. It's sort of the most fundamental possible decomposition of that problem."}, {"start": 579.6, "end": 608.21, "text": "And in software, I feel like we haven't quite refined this notion. You can look at some code, you can be like, this is good code or this is bad code, but can you really look at a system and say, this is a good way of architecting the system or this is a bad way of architecting the system? And I think that the answer is you can, and that you should take the mathematical approach to that. You should say that a system decomposition is good if it is the simplest possible way of doing it, if everything falls into place naturally, and importantly, that..."}, {"start": 608.21, "end": 636.93, "text": "In mathematics, you don't think about, I am the one who is designing this. I am the person who's creating this mathematics. You think, I'm discovering it. This is just something that happens to be true about the universe. And look, I happen to be the first person to come across it. And in software, I think we usually think the opposite, which means that we usually stop short of actually taking things to that real extreme simplicity. And I think a good example here is the way that Heroku does deploys. And so with Heroku, you just do a git push."}, {"start": 636.93, "end": 665.55, "text": "And that Git is this tool that you already have on your computer, that you don't have to install some third party thing. It's all just there integrated into your workflow. And that kind of simplicity, I think, is what everything should strive for. It would be very easy to just say, oh, we're just going to have some clients that everyone's going to have to install. But I think being able to go to that extreme is something that's really important and that we should do more of."}, {"start": 665.58, "end": 695.28, "text": "A second one, which I actually think is very nuanced, is that you should understand how your abstractions are implemented. So in math land, you actually just cannot do math if you don't understand how all of your underlying theorems are approved. The kind of thing that will happen is that you have this statement, and in theory, you should just be able to apply this statement in all the cases where you have some data that fits the right form."}, {"start": 695.28, "end": 724.26, "text": "You just won't really be able to manipulate any of your things into an appropriate form if you don't understand where that theorem came from. You really have to understand not just what's the headline statement and sort of, if you think about it in software terms, what's the interface to this, but you really have to understand the depth. How did this theorem get arrived at? What is the real reason that it's true? And that will help you manipulate whatever problem you're trying to solve into the appropriate form. Now, in software,"}, {"start": 724.26, "end": 748.26, "text": "You don't have that extreme that you definitely can get by without understanding how any of your abstractions are implemented. If you think about, for example, an ORM, that you can just use that and that you'll successfully be able to make SQL queries. But there are sharp edges that as soon as you try to make a system which is sort of the best possible system that is decomposed in the best possible way, if you don't realize that..."}, {"start": 748.26, "end": 774.8, "text": "If you just use your ORM in the obvious way, you're going to end up with n plus 1 queries. Then suddenly, your system's going to grind to a halt. You're going to have bad performance. And in general, what this works out to is not just that abstractions are leaky, but that you just fundamentally can't use abstractions in the correct way without understanding where they come from. And so actually, my third and last"}, {"start": 774.8, "end": 801.63, "text": "Parallel here, or learning that I've taken away from mathematics, and there are a lot more, but we're relatively pressed for time, is that when you're building software, you should design it down. You should start with, you have the system, decompose it into fundamental parts. But when you're actually building it, you should build it from the ground up. What I mean there is that if you think about math,"}, {"start": 801.63, "end": 825.97, "text": "You don't have any tooling. You're there climbing up this cliff face. And the only way you can know whether or not the math that you're producing is accurate is by working through everything by hand. Any mathematician will tell you that this work over here is brute force and that sometimes it's necessary, but it's never something that's elegant or interesting or fun."}, {"start": 825.97, "end": 852.93, "text": "And that work over here, which is sort of the high level design stuff of actually figuring out how your problem fits together, that that's the interesting stuff. That's very cerebral. That's the kind of thing that a human should be doing. And that in software, you sort of have this opportunity you don't have in math, which is that you can, again, shell out to your computer to take care of all of the brute force for you. And so I think that the interesting thing on the math side is that"}, {"start": 852.93, "end": 871.39, "text": "It's a place where they clearly feel this pain of not having any tools that are able to take care of that kind of work for them. And so the fact that in the computer world you have that means that you should take full advantage of it. And so the way that I usually recommend doing things is that"}, {"start": 871.39, "end": 896.11, "text": "Again, you sit down. You figure out how you want to decompose your system into these components. And then you figure out, what's the minimum possible thing that I can do to get something that will run? And I think that the way that Kent Beck was talking about this is pretty good, that you just want to get something up and running, and that you just iterate from there. Anyway, that's everything that I have. Thanks."}, {"start": 901.39, "end": 921.41, "text": "Can I ask about understanding abstractions and implementations? Is that really realistic given that software today is abstraction on abstraction on abstraction, even the OS is an abstraction that mortals cannot hope to understand? Right. So I think that the way that you have to do it is that the layer that you're building at, that you should understand the abstractions beneath it."}, {"start": 921.41, "end": 933.39, "text": "And that I think that if you're building a software project and you are the one who's creating those abstractions, you should create them in such a way that the immediate consumer of those is going to be able to dig into it and trace issues and figure out what's going on."}, {"start": 933.39, "end": 961.46, "text": "As soon as you go a step down, it's pretty unlikely that people are going to have to trace through it. But the thing is that there often will be cases where they will. There will be cases where the way that your system is paging ends up impacting performance in some weird way. There are going to be issues where there's a kernel bug or things like that that will ultimately impact people at the application layer. And so I think the answer is you can get by with incrementally better systems by people who understand incrementally"}, {"start": 961.46, "end": 990.94, "text": "Deeper parts of the stack. I think that there's diminishing returns as you go deeper, though. Okay. I'll give Sven a question. Come on, Sven. What's your question? It sounds like a pretty strong case for open software because when in maths, you can look at the theorems because they're all published. You can read through the theorem itself. And if you're using a library and you can't read the source code of it, then you have no idea of how the things are implemented."}, {"start": 990.94, "end": 1020.59, "text": "This is quite important. In Java, for example, I have all libraries in Java available. I can look at them and can see how they're implemented. Yeah, I agree with that. I think with all these things, you can get by, and that's actually something that's different about software than math. You literally could not get by if we closed-sourced all of the proofs of theorems. But I think that you'll be limited in how good your systems can be, or you'll have to put in way more effort to get your systems to a certain point if you can't read the implementation of the libraries you're using."}]}