Check out a free preview of the full The Good Parts of JavaScript and the Web course

The "Function Challenge 1" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:

After a brief explanation of the setup, Doug gives the audience a quiz. Then he begins the Fun with Functions exercises.


Transcript from the "Function Challenge 1" Lesson

>> [MUSIC]

>> Douglas Crockford: I'm gonna give you a series of problems. A problem might look like this.
>> Douglas Crockford: Write an identity function that takes an argument and returns that argument. And I'll show an example of how you would call it and what the result of that call would be. I will then give you some time to work on it.

Probably about ten minutes or so. Some of you are gonna work faster than others, so for those of you who finish quickly, you're gonna get frustrated, because you're gonna have to wait for the time before we go on. And for some of you are gonna be working slower, and you're gonna get frustrated cuz you might not have enough time to finish every problem.

So, my goal today is to frustrate everybody equally, okay? That's where we're gonna be going with this. So, you'll take some time, you'll work on the problem, you'll come up with the solution. I will then show you my solution. And in some cases, I may show you multiple solutions and you can compare yours with mine.

If you like mine better than yours, you want to record it, because each of these later problems will refer to earlier problems. Either in pattern or we'll actually be calling the earlier functions, so make sure that you get at least one version of everything that works. Also, I highly recommend that you use exactly the same function names that I do, because later we're gonna write functions which call these functions, and if you're giving them different names, it'll be really easy to get confused, okay?

>> Douglas Crockford: Then you'll probably want to test it. If you have a JavaScript engine on your machine and how to use it, for example, if you have Node installed and you know how to use the repo, that's great. You can just plug it in there, and it'll work. If you don't, you have at least one web browser.

And all the web browsers now come with very nice debuggers, so you can do that as well. This is one way to use a web browser. You could simply have a form like this, or a page containing a script tag. For my convenience, I created a log function so I could log results, and it'll just write them to the screen.

Then in the box, I've got the function that I wrote, and then I called the function sending the result to the log. If you wanna do something more sophisticated, you're certainly welcome to do that. This is sort of the minimum that you need to get started. You don't have to test your functions, but you probably want to, right?

Cuz otherwise you can't have confidence that they're working correctly. While everybody is still getting set up, we're gonna do a quiz. Pop quiz. So here we go, ready? Question number one, we have a function called funky. It takes an argument o, sets o to null. We create a global variable x, which is an empty array, we pass x to funky.

What is now the value of x? So who thinks x is null? And who thinks x is the empty array? And who thinks it's undefined? And who thinks it'll throw an exception? Okay, the answer is B, the empty array. So let's look at what's happening here. So if we start off, we have the global variable x that points at the array.

We pass the contents of x, which is that reference to funky, which has it bound to o. We replace o with null. And then there you are. So funky, as written, is a completely useless function. And in this thing about the way variables work is not peculiar to JavaScript.

Almost all modern languages work this way. Most languages do not allow you to pass a reference to a variable. What they allow you to do is to pass a reference to the contents of the variable, okay. ALGOL 60, which was a brilliant language, had something in it called, call by name, where you actually could pass a reference to a variable.

That was one of the very few, very bad ideas in ALGOL 60. Ready for another one? Okay, here's a function swap, takes two arguments a and b, and it swaps them using a temp variable. We have two global variables, x and y, whose values are 1 and 2.

We pass x and y to swap, what is now the value of x?
>> Douglas Crockford: So who thinks x is 1? Who thinks x is 2? Okay I'm not gonna fool you this time. The answer is 1. And it's similar to what we did before. So here we've got our two global variables, x and y, that point to 1 and 2.

We pass x and y to swap. Then we fiddle them around with swap, but that did not change what x and y are doing. I'm hoping that some day in the future, JavaScript gets macros. So instead of saying function swap, I'd say macro swap. And in that case, macros do get called or do get passed with variable names, and macro swap would be useful thing, but as written, function swap is pretty useless.

Okay, any questions about the quiz? Okay, quiz is done. It's time to do some real work, are you ready? So the first one is going to be totally trivial, no tricks, it's just something to allow you to test your environment. So write three binary functions. A binary function is a function that takes two arguments.

Add, sub and mul, that take two numbers and return their sum, difference and product, okay. This is as trivial as it sounds. There are no tricks. We're doing this so that you can practice and also so that we'll have functions that functions that we write later will be able to call.

So here we have add, first and mul. I assume that everybody got this, right? Yes, who got this? Yeah, if you didn't, write it down because you're going to need these for later. Okay, ready for the first interesting problem of the day? Here we go. Write a function identityf that takes an argument and returns a function that returns that argument.

So, we're gonna call it identityf, we're gonna pass it 3. That will return a function. When we call that function, it will return 3. So, here is identityf. identityf takes an argument and returns a function that returns that argument. So who got identityf? Very good. If you didn't get it, write it down, because you gotta definitely need it later.

And don't be discouraged, I'm not expecting everybody to get every problem. What I'm expecting is that everybody gets the last problem. Okay, so if you don't see what's going on immediately, just stay with it. Eventually the patterns should start to become clearer and you'll get a sense of where we're going, okay?

Any questions so far? Okay, are we ready for the next one? Okay, write a function addf that adds from two invocations. So if we pass a 3 to addf, it would return a function. If we pass 4 to that function, it will return 7. So here is addf.

addf takes a first argument, it returns a function that takes the second argument and it returns the result of calling the first and second argument. So who got addf? Okay, very good. If you didn't get it, write it down. You're gonna wanna need it for the next one.

So this problem was suggested to me by Dmitry Baranovskiy, who is a brilliant Ukrainian programmer living in Sydney, Australia. He's the author of RaphaelJS, a very nice graphics package for the browser. He suggested that this should be a hiring question, and if you got this right, maybe you think so, too.

So we ready for the next one?
>> Douglas Crockford: Okay, here we go. Write a function liftf that takes a binary function and makes it callable with two invocations. So, if we pass the add function that we wrote the first thing this morning to liftf, it returns a function that works exactly like the addf function that we just wrote.

And to make it even more interesting, we can pass other binary functions, like the multiply function, and get a similar kind of capability. Let's look at liftf. Liftf takes a binary function, returns a function that takes a first argument, that returns a function that takes a second argument, that returns a result of passing the first and second arguments to the binary function.

So who got liftf? Very good. If you didn't get it, write it down. You're gonna want to need it for a later one. This is an example of a higher order function. Higher order functions are functions that receive other functions as parameters and return other functions as results.

So we're starting to get moving down the rabbit hole into a very interesting way of constructing things.

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