Transcript from the "Provable and Readable" Lesson
>> Kyle Simpson: I think one of the most important answers to the why functional programming is this concept of provability. What functional programming seeks to do at least from my perspective, what it seeks to do is to use patterns that have already been tried and tested and proven and not for like two years.
[00:00:23] You know how we get all excited. Cuz two years ago, somebody invented Reactor. 3.5 years ago, they invented Angular and we're all hyperexcited about that. In a year from now, we're gonna be excited about Vue. And then a year after that, we're gonna be excited about whatever that thing is that somebody in here is inventing.
[00:00:39] Because we have this very small, almost myopic view of innovation and of the deep thought processes that go into building this stuff that we use the foundations that we walk upon. These are ideas that have been around for like 50 years or more. As a matter of fact, the mathematical principles underneath them had have been around for hundreds of years not a couple of years and they don't just have a couple thousand people starring the repo on GitHub.
[00:01:13] We've got tens and hundreds of thousands of mathematicians, and computer scientists that have vetted these ideas, and they've proven these ideas work. And what they've said is here's this crazy term monoid and it describes this thing, which is proven to do a thing you wanted to do. So use it, so that your code in that part has a proof to it.
[00:01:39] Many of you probably know that it's important to have tests around your code and I certainly agree with that. You should have unit tests. You should have integration tests. But there's a hint here that in a sense, the aspiration should be that we should write a piece of code and know verifiably, provably what it's gonna do without even needing the unit test.
[00:02:04] Like I already know the unit test is gonna pass, cuz I used a mathematically proven concept to model it and you're not gonna argue with math. If you get a bug and the unit test doesn't pass, it's cuz you didn't implement it correctly. So I think the functional programmer says, let me try to use mechanisms that are proven.
[00:02:28] And you might wonder, okay, is that just like an academic exercise? Do you just make yourself feel clever, because your code is more provable or something like that. There's something much deeper here. Not only does provable code make it so that you can understand that code better, because I've said this before and I'll say it a million more times.
[00:02:49] Code that you do not stand is code that you cannot trust and the reverse is also true. Code that you cannot trust is code that you cannot understand. If you cannot trust that it will do exactly what you want it to do, you don't fully understand it yet.
[00:03:09] Let me ask you this way, how many of you ever had a piece of code break and you weren't sure why it broke? Anybody? We're all mostly raising our hands. We're in good company. Let me ask a more profound question, how many of you have had a piece of code work and you didn't know why it worked?
[00:03:28] It's a little closer to the heart, doesn't it? So we have to admit that, but it's true. We all do this and I include myself. I wrote code a few days ago on the plane ride here, I don't know how it works. Literally, I don't know how it works.
[00:03:43] I don't fully understand what I did. So, code that you can't trust is code that you can't fully understand. In a functional program, it says, one way to trust my code better is to use a pattern that's already been mathematically proven. I don't need to go figure that part out again.
[00:03:59] I just need to understand it and then understand how to put it together, and then understand this other Lego piece and how it fits in, and what their effect together will do. And I just build my program as a series of those assertions. Removing large swaths of the program from the sphere of concern.
[00:04:20] There are parts of your program that you're always gonna have to wonder about, your business logic, your validation rules. But there's also large swaths of the program that represent verifiable transformations on data that you shouldn't have to worry about. You should be able to fully trust it. It should be provable and your own intuition about how to prove stuff with a unit test is not as good as the stuff that's been proven by mathematicians for hundreds of years, and by computer scientists for decades.
[00:04:55] It's just not. So in a sense, I think a functional programmer admits that. Says, I need some help. So, I'm gonna use this domain called functional programming to find patterns that I can use in my code that have already been proven. But there is something deeper and this is I think the ultimate motivation, the ultimate question.
[00:05:18] Code that's already been proven and code that's already recognizable as such. Meaning, if you structure it in such a way that it is easily at a glance recognizable as an implementation of that proven theory, also means that, that code does not have to take up the neuron processing time in you brain as you read the code.
[00:05:44] What I really think the deepest motivation for functional programming is, it's not just to help you, the author of the code have a confidence and a level of provability and trustability to what you've written. But it is also to help the reader of your code be able to trust that they don't have to worry about how these parts work.
[00:06:04] They know what they do. They know that you're using them. There's a part of the code I don't need to read and I'll make the almost silly assertion. The most readable code is the code that doesn't have to be read at all, because our brand should be focused on the stuff that really matters.
[00:06:26] The high-level, macro-level, business logic, validation rules kinds of stuff use on our action rules, all of that. That's what we should focus on, but we get so distracted by focusing on all this other stuff. And a function department says, why don't we just do all that other stuff in our provable trusted way, a recognizable way?
[00:06:46] That way, the reader of the code doesn't need to worry about that part anymore. If they recognize it, if they've learned what it does, I don't need to think about it. Imagine the mountain climber having to think at every single moment. Now, how does this carabiner work and what is this rope doing?
[00:07:01] I don't even know what rock climbing equipment is, so I'm just pretending. I've just Googled stuff. Imagine him having, while on the face of a mountain, having to think about all those individual little things. Would that be an effective way to climb a mountain? I don't think so.
[00:07:20] A mountain climber trusts his tools. The mountain climber knows what the rope does and knows what the carabiner does and knows that if he falls, it's gonna catch him.
>> Kyle Simpson: A functional program are trust as tools. Knows what it's gonna do. Functional program are trusted tools used by others.
[00:07:39] And when they read their code, they don't have to go second guess that stuff. That helps code be more readable. And ultimately, the reason I think code readability is so important is because the most important thing that we can be doing as programmers is communicating with other human beings.
[00:07:58] That's not a unique thought to me, but I believe it deeply. Almost at a religious level that our goal should be to better communicate with other people. The computer is already figuring out from what you write, whatever amazing code you think you've architected. The computer already looks at it and says, thanks very much for that suggestion.
[00:08:17] But I'm gonna do it in an entirely different way. Thanks very much. Why do we get so obsessed about what we write as if the computer cares what we write? Why don't we focus a little bit more and a lot more on structuring the code, so that other readers including your future selves have an easier time understanding what's going on.
[00:08:44] That to me, at least at this point in my journey, I'm a little bit further up the cliff face climbing than you are. That to me is the why we're climbing the mountain. That's why functional programming. Use mechanisms that have been proven not only so that you have a confidence over your code and you understand it, but that the reader of your code has the same level of confidence and understanding.
>> Kyle Simpson: So, let me pause there for a moment. Any thoughts or questions about those assertions before I move on? Yes.
>> Speaker 2: Just one question from online. Craig asked, when you move from imperative to declarative, are you increasing the level of abstraction?
>> Kyle Simpson: Abstraction is a funny thing and we're gonna talk more about abstraction, but it's one of our fundamental.
[00:09:39] It's one of our most important concepts in programming. And yet, I think a lot of people have the wrong intuition about what abstraction really is. I bet if I were to poll each of you and those of you online and I were to say, tell me what, if we were in a job interview and I gave you the job interview question, tell me what abstraction is.
[00:10:01] Define abstraction. Give me examples of abstraction. I bet what I would hear from most of you is something along the lines of well, abstraction hides details. Something to that effect. We think about class-oriented coding or hiding details inside of the class implementation and we call that an abstraction.
[00:10:23] That's not really what abstraction is or at least it's not what abstraction was originally designed to describe. That concept, hiding details in particular has a different term and that's called encapsulation. Abstraction is a little different. Abstraction actually comes to us from a very old root. If you think about the word complex, that comes to us from the Latin root for complect or complected and that comes to us from this idea of the strands of a rope being tightly braided together.
[00:11:00] And we know a rope that when it's braided together, it's much stronger. But we also know that if you have a tightly braided strands of rope and then you wanted to take just one of the strands out, that would be virtually impossible. So, complected comes to us from this idea of having things tightly wound together.
[00:11:20] And actually, we get simple as the opposite of that where things are completely separate and that's really what abstraction was actually about. It was not about taking some detail and hiding it away, so we don't have to think about it. Rather, it was taking two or more things that were tightly wound together like the strands of a rope and teasing them apart, separating them and putting intentionally between them a semantic boundary.
[00:11:51] Not so that we don't have to think about one or the other, but so that we can comfortably sit on either side of that semantic boundary. Understand what that thing is in its full and completeness without worrying about the stuff on the other side of the boundary. Abstraction is about creating semantic boundaries between things.
[00:12:11] So in a sense, the question that was asked is imperative to declarative. Is that move towards declarative about adding extra, extra, abstractions? In its pure essence, yes. But it's not about hiding things. That's not what we wanna do. It's about creating the appropriate layers of separation. The appropriate boundaries of separation, so that we can independently think about, reason about and prove each piece.
[00:12:39] That's what it's really about. We're gonna see many more examples about this, so I'm not gonna get any further into that discussion of abstraction. But I wanted to provide some more color to that question. In the basic sense, yes, it is. But it's about adding the right kind of abstraction.
[00:12:56] There's lots of abstraction you can do. There's lots of things you can do and call them abstraction that aren't going to aid us in that goal.