Functional-Light JavaScript, v3

Referential Transparency

Kyle Simpson

Kyle Simpson

You Don't Know JS
Functional-Light JavaScript, v3

Check out a free preview of the full Functional-Light JavaScript, v3 course

The "Referential Transparency" Lesson is part of the full, Functional-Light JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle explains the final requirement for functional purity, referential transparency, which is when a function call can be replaced by its return value without affecting the rest of the program.


Transcript from the "Referential Transparency" Lesson

>> Kyle Simpson: We're finally ready to get the final answer, at least for the purposes of this course, to what is a pure function. Okay, let's review where we've been so far, we started with a pure function needs to take some inputs and return an output, so where we started, the very, very beginning.

That was good but not good enough. And then we said, well no, actually it needs to have a relationship between the inputs and the outputs, which was better but still not good enough. And then we said, well no, actually they need to be direct inputs and direct outputs, which was good but not good enough.

And then we said, well no, actually they don't have to be direct inputs, they can be indirect as long as they're not changing. Remember, we can close over stuff as long as not changing, which was even better definition, but still not good enough. And then we said, well, actually the real thing is, it's the function call that every time I call the function with the same inputs, I should get the same output.

If that's true, then I have a pure function call, right? Even better definition, but still not complete. Here's the full, canonical, complete definition for a pure function, and specifically for a pure function call, remember, we're focused on the function call. Line 9 is a pure function called because or if.

I could take the return value of that function call, and replace the function call with the return. In other words if A was somehow being used somewhere in the program, like it was part of some other expression, which always returns the string, if I could take the string AAAAA and literally just replace the function call with that volume.

If I could do that and not affect any of the rest of the program, then I have a pure function call. There's a very special term, again, if you say this to your co-workers after the course, you're gonna sound much smarter, so use it, use it with your boss.

The term is called referential transparency. Sounds cool to say doesn't it? A function call is pure if it has referential transparency. Referential transparency means, a function call can be replaced with it's return value and not affect any of the rest of the program.
>> Kyle Simpson: Now it turns out referential transparency, that's a really key idea, it turns out that in a language like, for example, Haskell, the granddaddy of functional programming, referential transparency is a key characteristic of the language end of the compiler indeed.

Because in Haskell, when you write functions they're always pure, which means they always have referential transparency, which means that because that's a guarantee of the language, the compiler can take advantage of that. It literally normalizes everything, because it can do that for free. It can literally replace other function calls with the inline result of the previous function call, they do that automatically for free because they have that guarantee of the language, we do not have that in JavaScript.

So, does referential transparency only matter if the compiler can do it? Some would say yes, but I would say no. In a bigger sense, the real benefit of referential transparency is actually to the reader of the code. Consider any function call in a program that is indeed a pure function call.

The reader of your code reads line 11, and they go and they compute it, they say, okay, I know that line 11 is this value, the value 42, or whatever. Everywhere else that they see that exact same function call anywhere later in the program with the same inputs, do they need to go re-compute the result?

No, because what are they gonna do? They're gonna referentially swap out the function call for the result they've already computed in their head, and what's that gonna do? It's gonna free up their brain power to focus on other, more important parts of your app. So referential transparency, while it matters a lot to the compiler in something like Haskell, for us in JavaScript, the reason it matters is because it puts the responsibility on you, the author of the code.

To make it as easy as possible for the reader of your code, which includes your future self, to be able to look at a line and know exactly what it's gonna do, and then not have to redo that work over and over, and over again. I said at the outset of this course, the best code is the code that didn't have to be read in the first place.

Cuz I looked at it and said, I've already done that, I don't need to do that. That's why function purity matters so much. It's like we're building up this pyramid, and this is the base stone of the pyramid, and if you take it out everything else would crumble.

You cannot have anything else in functional programming unless you get the value and the importance of function purity. Function call purity specifically

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now