Transcript from the "Arguments" Lesson
>> Kyle Simpson: So we're starting to evolve that mindset of purity towards, and we're not fully there yet but now we understand a few more sides of the Rubik's Cube. It's about the observational output and it's really about my level of confidence that it's going to do what I expect.
[00:00:13] And it's important for us, as the authors of code to give as much of a clue to the reader as we can that they can trust something. The more we do to erode that trust, the harder we make the code to read. It's on us, the author of the code, to signal to them this code is going to behave the way you think it's going to behave.
[00:00:39] We shouldn't do stuff like make a getter that returns random numbers okay? Let's talk about arguments, an unsung, not particularly well thought of or often thought of part of what makes a function a function is how its arguments work. And I want to spend some time thinking about, talking about arguments.
[00:01:04] There's a characteristic, or a term used to describe something about functions that is going to turn out to be pretty important to us. Hopefully these terms aren't that scary to you. If I have a function that takes only one parameter, expects only one parameter, there's a special term for that kind of a function, it's called a unary function.
[00:01:27] On the other hand if I have a function that expects two parameters, like the one on line 7, that function has a special term called binary. Unary for one, binary for two, three or more has another term called n-ary.
>> Kyle Simpson: So unary and binary, you typically don't like to see a lot of n-ary functions in a functional program.
[00:01:59] Three, four, ten inputs, those are really hard to work with. It's also just really hard to remember what all of those are. So generally speaking, you probably want to shy away from designing your functions with 15 different input parameters. Try to stick to your unary and binary functions wherever possible.
[00:02:21] Now turns out that sometimes you'll have a function that expects more arguments and you need to produce a unary or a binary function from it. So we're doing a higher-level operation here, a higher-order operation, because I'm taking, you'll see unary there on line 1. That is a function that takes a function as an input, makes a new function that only takes one argument.
[00:02:48] And when that new function is called, it only passes along the first argument. So I make g as the unary(f), f is a function on line 13 that can take any number of arguments. There's a special term for that, it's called a variatic function cuz it can take any number of arguments.
[00:03:11] g takes that variatic f and turns it into a unary function. So even on line 20 when I pass in multiple inputs (1,2,3,4) I still only found one input to the underlying f function. That's why it printed out the array of just the value 1. So I've constrained the inputs to that function, that's what unary does.
[00:03:39] Binary does the same thing, but it does it with two arguments. h is the binary wrapper around that variadic f. On line 21, when we call h with multiple inputs, we only get two values printed, the array of 1 and 2.
>> Kyle Simpson: These utilities, unary and binary as described here, exist in all of your common functional programming libraries.
[00:04:05] And they turn out to be really useful to us in terms of describing I've got this problem. I need to take this function that expects multiple things and make it so it only expects one or two or something like that. It's a way to adapt that function that turns out to be very useful.
>> Kyle Simpson: Sometimes you'll have a function that takes arguments in a certain order, and that order is inconvenient to you. Sometimes that order will not be the order that you wanna go in, and so you could define a utility like this one called flip. Which takes a function, produces a new one, which will flip the first two arguments.
[00:04:47] You'll notice that I have arg1 is flipped there. arg1 from line 2 shows up in the second position on line 3, and vice versa with arg2 from lines 2 and line 3. So the flip utility makes a new function g that will transpose, that will flip the first two arguments passed in.
[00:05:10] When I call g(1,2,3,4) I get a console log output that is 2,1,3,4, flips the first two arguments. These are all things that a functional programmer has to get very comfortable with doing. You have to juggle the order of arguments, sometimes you have to constrain the arguments. The arguments to a function really matter and the way you design your function really matters.
[00:05:36] If you design a function that expects x and then y. And then everywhere that it is used in the program you need to provide them in the opposite order so you have to flip that thing. Then you probably should go back and redefine the function to flip the order around.
[00:05:54] So you don't make somebody have to call flip every time. You follow where I'm coming from here? The order of arguments matters, and a functional programmer develops a sensitivity to make sure that they design their functions so that they're as easy to use as possible. They say what is it most commonly?
[00:06:14] Will they provide this one first or this one first? Or this one, or this one, or this one? The order that you decide to author your functions will definitely matter.
>> Kyle Simpson: Sometimes you get it all wrong and you need to not just flip the first two but like completely reverse the entire list of arguments.
[00:06:33] Here reverseArgs does that. reverseArgs takes in whatever arguments you passed in and just flips that whole list completely inverses the order. So now g when I pass in (1, 2, 3, 4) I get back the array or I print out the array of [4, 3, 2, 1]. So it's a more substantial change than what flip is,
>> Kyle Simpson: Sometimes you wanna pass in an array and have the contents of the array treated as if they were the individual inputs. On line 13, I'm passing an array of (1,2,3,4) to a g function. g is the spread or it's also referred to in functional programming libraries as the apply of f.
[00:07:20] f is expecting individual (x, y, z, w). We wanna take the contents of the array (1, 2, 3, 4) and spread those out. Or the functional term is apply those to those individual parameters inputs, spreadArgs utility does that for us. Now I don't have a slide for this but I just want you to pause for a moment.
[00:07:46] How would you do the reverse? There's a spreading argument where I wanna pass in an array and have it spread out to individual arguments. What if I wanted to pass in individual arguments, but have them come in as an array?
>> Speaker 2: You could use the rest args.
>> Kyle Simpson: Remember the functional programmer's defining utility is to adapt their functions here.
[00:08:13] We're talking about adapting a function written in certain way to work another way. So if I had (1,2,3,4) that I wanted to pass in as individual arguments and the f function expected a single array. And I can't change anything about the definition of f, how could I make a utility that would adapt f to be what I need it do?
[00:08:34] And there's a term for that in functional programming, it's called unapply. It's the reverse of apply, I like to call it gather cuz it would gather individual arguments into a single array. We'll leave that as some homework for you to think about. How would I make a version of spreadArgs that was called gatherArgs that took individual arguments and gathered them into an array.
[00:08:58] It's actually not very hard at all, but just think about that as some homework here.