This course has been updated! We now recommend you take the The Good Parts of JavaScript and the Web course.
Transcript from the "Problems 6-9" Lesson
[00:00:00]
>> [MUSIC]
[00:00:04]
>> Douglas Crockford: Yeah, everybody ready? Okay, here's the next one. Write a function that takes a function and an argument, and returns a function that can supply a second argument. So this is sometimes called the curry function. So curry(add, 3) produces an add3 function, and we can call that with 4 and it returns 7.
[00:00:29]
>> Douglas Crockford: Does anyone need more time?
>> Douglas Crockford: All right, so here it is. Function curry takes a function and a first parameter and returns a function that takes a second parameter, and returns a result of calling the function with both parameters. Who got this one? Outstanding, who's still struggling with this, and,
[00:00:57]
>> Douglas Crockford: Where are you getting hung up?
>> Speaker 2: I think a key point I was missing on the first example was that the function that's being provided is expected to take two parameters. I was trying to play in my head with the function that could take more than two, and that was really tripping me up to try and figure out when I should actually be invoking the function in question.
[00:01:19]
>> Douglas Crockford: That's interesting, we'll talk about that in a minute.
>> Speaker 2: Yeah.
>> Douglas Crockford: Anybody else?
>> Speaker 3: Same as him.
>> Douglas Crockford: Yeah, okay, so this is called currying. It's also called schonfinkelisation. It's called currying after Haskell Curry, a mathematician who did work on lambdas and functional forms. The idea of being able to take a function of many arguments and turn it into something where you express functions having only single arguments, make certain kinds of transformations easier to reason about.
[00:01:51] And there's some consensus that Schonfinkel came up with this stuff before Haskell did. So they think it should be called schonfinkelisation, but that's not really catching on, so it's called currying. Now another way you could have written this, this is for extra credit, you could've used the applyf function that you already wrote and done it in terms of that.
[00:02:15] So I don't suppose anybody did that one, but you would get an extra credit.
>> Douglas Crockford: Then some people like to write this for any number of arguments, not just one, but have many arguments going into the currying. And unfortunately, that is horrible to do in the current language, because the arguments array is not really an array.
[00:02:39] And so you have to do all of this horrible stuff to get around the fact that it is not an array. Calling things off of Array.prototype, and slicing in order to convert it from one form to another, terrible. In the next edition of ECMAScript, we'll probably have a dot dot dot operator, which looks exactly like the other solution, except you have dot dot dot for everything which could represent multiple arguments, which is brilliant.
[00:03:09] This is gonna be my second favorite feature in the next edition of the language if it ever comes out.
>> Douglas Crockford: So any questions about curry before we go on to the next one?
>> Douglas Crockford: So if you've had dot dot-
>> Speaker 2: Looks like that.
>> Douglas Crockford: Yeah, you're struggling with that, right?
[00:03:26]
>> Speaker 2: Right.
>> Douglas Crockford: I feel your pain. That is really awful, awful code, whereas this would have been just dot dot dot, give me more. Okay, so now the next one. Without writing any new functions, show three ways to create the inc function, where the inc adds one to a number.
[00:03:50]
>> Speaker 2: We can't write the inc function ahead.
>> Speaker 3: [LAUGH]
>> Douglas Crockford: No, you're writing no new functions, only calling functions that you've already written.
>> Douglas Crockford: Show three ways to create an inc function.
>> Douglas Crockford: This is where it starts to become useful, where we can use functions as factories for making sets of related things.
[00:04:26]
>> Douglas Crockford: In this case, you've already written three functions that know how to do this.
>> Douglas Crockford: All right, so here we go. Number 1, addf(1). Number 2, applyf(add)(1). And curry(add, 1). So who got all three? You think you did? Who got two?
>> Speaker 2: I forgot that we had written addf.
[00:05:01] I didn't realize you wanted three different inc quotations.
>> Douglas Crockford: Yeah, and who got one? Okay, and who struggled with this one?
>> Douglas Crockford: So the point of this one was part of the value of thinking in functions is looking for work that you have already done and factoring that in.
[00:05:21] The whole point of this is, surprising as it may seem right now, is avoidance of work.
>> Douglas Crockford: Okay, write methodize, a function that converts a binary function to a method. So here, we're gonna create Number.prototype.add and pass in the methodization of add.
>> Douglas Crockford: So methodize has to create a function that will use this as one of the parameters to the addition.
[00:06:04]
>> Douglas Crockford: Any questions about this?
>> Speaker 2: I can't really wrap my head on the problem.
>> Douglas Crockford: Okay, so one of the interesting things, okay, so numbers are objects in JavaScript, which means they can have methods. So when you call a number method, this gets bound to the number.
>> Speaker 2: Right.
[00:06:23]
>> Douglas Crockford: So the add method takes only one parameter because the other parameter comes with this.
>> Douglas Crockford: But we're trying to transform the original add function which took two parameters. So we want to return a function which takes the add that we pass in and returns a function that knows how to use this.
[00:06:50]
>> Douglas Crockford: So the point of this is if you have an existing function and you need a function which is exactly the same, except slightly different in form, you don't have to rewrite the function.
>> Douglas Crockford: Okay, so here it is. Methodize returns a function that takes a y that returns the calling of func with this and y.
[00:07:21]
>> Douglas Crockford: So who got this one?
>> Speaker 3: [LAUGH]
>> Douglas Crockford: [LAUGH] And then this shows in ES6, it will be easy to have functions that aren't just binary functions, but functions of any arity with the dot dot thing, which will be nice, but that's the one I was looking for.
[00:07:41] So was this one harder maybe than the other ones? And why was that?
>> Douglas Crockford: Anybody?
>> Speaker 2: I originally thought I could get away with using curry this, but that did not work out. Cuz my list was not properly scoped.
>> Douglas Crockford: Yeah, this is problematic within functions that you only get to use it at one level.
[00:08:10]
>> Speaker 2: Can we go back one screen just for a second?
>> Douglas Crockford: Yeah, let's see with the other one.
>> Douglas Crockford: Okay, ready for the next one? Okay, write demethodize. Demethodize is a function that converts a method to a binary function. So we're gonna reverse what we did to Number.prototope.add so that after we demothodize it, we can now again pass it two parameters.
[00:09:05]
>> Douglas Crockford: So we'll take a function that takes this kind of parameter and turn it into a function that takes two parameters.
>> Douglas Crockford: [LAUGH]
>> Speaker 3: [LAUGH]
>> Douglas Crockford: So I'm curious, who's thinking this is fun?
>> Speaker 3: [LAUGH]
>> Douglas Crockford: [LAUGH] And who's thinking this is work?
>> Speaker 3: [LAUGH]
>> Douglas Crockford: [LAUGH] And who's thinking it's torture?
[00:09:49] Not a-
>> Speaker 2: This feels like the kind of code you write to exercise a compiler [INAUDIBLE] business. It feels like a job [INAUDIBLE].
>> Douglas Crockford: [LAUGH] Well, I'm happy to tell you, there's no job at the end of it.
>> Speaker 3: [LAUGH]
>> Speaker 2: This is great material for interviews. [LAUGH]
[00:10:14]
>> Douglas Crockford: Yeah, I'll tell you my opinion on that. I don't believe in stunts as part of the interview process. The thing I like to do is invite people to bring in some code that they wrote that they're proud of and review it and have an independent. Cuz I wanna see what they think is good code.
[00:10:35] I want to see how it's constructed. I wanna see how it's commented, all that stuff. I don't get any of that from trivia questions or stunts or anything like that.
>> Douglas Crockford: Also, I would get a lot of that stuff wrong. If someone starts asking me about corner cases of the language, what would you do if you saw some code that look like that, I would say I would find that guy and I'd fire him.
[00:10:57] [LAUGH] And I can't tell you what that code actually does. I don't care.
>> Speaker 2: Probably talking
>> Douglas Crockford: All right, so here it is. Demethodize takes a function and returns a function and that and y and uses the call method on the function in order to set this with that.
[00:11:28]
>> Douglas Crockford: So we talked about call earlier, but I apologize. I might not have given you enough detail to have done this.
>> Douglas Crockford: So who got this one? Okay, a few of you did, really good.
>> Speaker 2: I have question. Since we're passing in a function, why can't we just return the function and send it to another variable?
[00:11:50]
>> Douglas Crockford: Yeah.
>> Speaker 2: What I had is basically demethodize equals function method, like you have done with the signature, and I'm just returning function, basically. So where you have the closure returning a function, I'm just returning func.
>> Speaker 2: Because presumably, the function already is the two parameter.
>> Douglas Crockford: Well, we start with a function which is a one parameter and this function.
[00:12:24]
>> Speaker 2: Yeah, but I just don't know if it's right. If it is return, took a function taking func, then it just returned another function that took two parameters. And then it did the param p1, returns p1 that then func param p2.
>> Douglas Crockford: We need to get that assigned to this somehow.
[00:12:56]
>> Speaker 2: Why wouldn't this [INAUDIBLE] here?
>> Douglas Crockford: Well, yeah, let's talk about it later.