Transcript from the "Pure vs Impure Functions" Lesson
>> Let's return to the concept of pure functions and just make sure that we are all on the same page about what a pure function looks like, and what a not pure function looks like. So right here I have two versions of a similar program, a very simple program, that basically outputs a greeting like, hello, Alonzo, or hello, Alan.
[00:00:25] Making reference to two of my functional programming heroes, Alonzo Church and Alan Turing. I'd like everybody to take a moment to take a look at these two versions of this code, and think about what the differences are. And keeping in mind that, pure functions have no side effects.
[00:00:48] In the not pure version, what side effects do you see? Okay, so we had a great comment that in the not pure function, it is kind of the hello is baked in. So it is not perhaps so, extensible to other types of greetings. Now, we're gonna talk a lot later about how functional programming helps us with reusability and code reuse.
[00:01:14] But in this case in this very simple example, that is sort of something that the two versions have in common, they both have this hello string baked in. So in this case, although it is absolutely a great point that functional programming helps us write more reusable code. In this case, the baked in hello is not technically a side effect, because it is not dependent on the outside world.
[00:01:42] Each of these functions, they have that hello kind of internally to them, so that's part of the operation, the computation that they're doing. It doesn't require, let's say, grabbing the greeting from a global variable or pulling the greeting out of some API endpoint or something like that. However, there is something kind of fishy going on in the not pure function in that sense.
[00:02:15] Yeah, Jordan go ahead.
>> In the not pure function, of course, the side effect being if that function is called at a later time when the variable changes, you might have an unexpected output. So the pure function you have an expected output, you're gonna pass it one thing and it's gonna return one thing.
>> Absolutely, really great point. So Jordan mentioned that, in the not pure function the name that's going to be output is being taken from a global variable here, that was declared above the function declaration, this name variable. And so, when I call this function the first time I get an output, hello, Alonzo that's based on the value of that name variable.
[00:03:06] But, let's say somebody else or maybe me after I've forgotten what this function is for, goes along and changes the value of that name variable replaces it with Alan. The next time that I call the function, because it's pulling from that global variable, I now get a different output.
[00:03:23] And so, what we've just encountered is one really great red flag for impure functions. Which is that, a pure function every time you call it with the same arguments in this case, no arguments or maybe the name argument. Every time you call it with the same argument, you will get the same result, that is a guarantee.
[00:03:51] Because, the result of that function depends on nothing about the outside world, only the arguments that are passed in. So, with the not pure version of greet here, we do not have a pure function because I can call this function the exact same way. I can call greet with no arguments at one time and get one value, and at another time, I can call it the exact same way and get a different value.
[00:04:20] And so, there's a term here called deterministic. So a pure function is deterministic, meaning it's output is totally determined by its inputs. And you will always get the same result when you call the function with the same arguments. Really great point. So that is one thing we notice about this not pure function.
[00:04:42] Erin, yes, go ahead.
>> Did not do one has no input and no output?
>> No input and no output for the not pure function, interesting. So no input, meaning there it takes no arguments. Now that's true, it might be a little bit of a yellow flag maybe for a function that takes no inputs.
[00:05:25] But if we don't have a return statement, that probably means that this function is doing something other than returning its value. In this case, what is this function doing other than returning its value?
>> Logging, exactly. So in this case, we don't really care about the return value.
[00:05:45] That's why we're okay with leaving the keyword return out of it, and just getting our regular old undefined as the return value. And instead what we're really interested in is logging to the console, which is changing something in the outside world. Printing a string like that to the console is a side effect.
[00:06:04] So yes, no return statement or not returning a value, huge red flag. But especially keeping in mind that, logging or updating the world in any way other than returning a value that is a violation of what we set up here function is. And so, those are some great red flags for identifying a not pure function.
>> I have a question.
>> Yes, question.
>> Does this mean calling a function within a function makes it not pure or is it just in this situation logging of course is putting something to the console and that makes it appear? Very interesting question. So if you call a function from within another function, does that make the outer function impure?
[00:06:57] So in functional programming, when we're doing it really, really deliberately, we would probably be passing in pretty much everything we need to work with as an argument to the function. However, that would quickly get very explosive. So sometimes it's a lot more convenient to actually use globally defined functions from within other functions.
[00:07:21] And in that case, whether or not the function that calls another function is pure is also going to depend kind of on the purity of the function its calling. So, if we are calling a function that we know perhaps, because we're being really disciplined about our function writing.
[00:07:45] Or perhaps because we're working in a functional language that forces all of our functions to be pure. If we know that, that inner function is pure, and that we're basically delegating some computation to it, then that doesn't necessarily mean, that we've got an impure function. Patrick
>> Yeah, so the pure function or the pure programmer doesn't actually do anything.
[00:08:08] If I were to run that pure program, it appears to me that it would just run and just not there is done nothing at all.
>> We've just encountered the big asterisk of functional programming. So Patrick raised the point. A pure function, if it's not allowed to do anything in the world except return its output value, it doesn't really do anything.
[00:08:33] I don't get any log output, I don't get my profile picture updated on the website. I don't get the light to blink if I'm working with LEDs or something like that. So I'm guessing the question is what gives? How do we do anything in functional programming? And this is a huge and super important question, so thank you so much for raising it.
[00:08:55] How do you be productive as a computer [LAUGH] programmer without ever doing side effects? Without ever writing things to consoles or storing things in databases or updating things elsewhere? You don't. This is the big gotcha of functional programming. When we're doing functional programming, we are concerned with the kind of computational aspect of our programs.
[00:09:23] What functional programmers do to be able to be productive, and to be able to actually affect the world. Because at the end of the day what we're trying to do when we write programs, is to take all of those side effects. All of those logs, and database transactions, and inputs and outputs from the outside world.
[00:09:42] And essentially push them to the outside of the program, so that they're kind of the very, very last step in doing any of this. And the inside of the program is all totally pure. Why would you do this? Well, we're gonna talk in a moment about some of the advantages of functional programming.
[00:10:04] But essentially, it means that, anything going on inside of your program, all the logic, all of the business logic. And the computations and the manipulations of data that are usually the tricky parts of getting those programs right, all of that becomes much more easier to deal with. Because it is more predictable, it's safer, we're gonna talk about that in a moment.
[00:10:31] And those impure side effects, we can force out to the outer edges of our program. So that we know, that, by the time we've gotten there all of our computations have already worked perfectly the way that we want. Because everything inside the program is deterministic, as we said is a great consequence of pure functions.