Check out a free preview of the full The Good Parts of JavaScript and the Web course:
The "Function Challenge 8" 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:

In this challenge, you will write the m(), addm(), and liftm() functions.

Get Unlimited Access Now

Transcript from the "Function Challenge 8" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Douglas: So this one's gonna be totally trivial. So I'm just gonna give you the solution. We're just gonna do this because it's going to set up the next problem, okay? So we're gonna write a function m that takes a value and an optional source string and returns them as an object.

[00:00:19] And in this case, instead of simply passing things to the log, I'm gonna be using JSON.stringify to make strings of the object because it turns out object.toString is completely worthless. It doesn't show you anything about what's in the object. It's just not worth it. JSON.stringify, on the other hand does a fairly good job of showing you what's in the object.

[00:00:46] So, in this case the stringification of m(1) is an object where the value is 1 and the source is the string 1, we make the string of the value. If we pass in a second argument, then that second argument will be the source property. So if we pass in pi and the word pi, the value will be pi, and the source will be pi.

[00:01:13] So this is the function, the constructor that does that. So go ahead and type this in, I'll give you a minute and then we'll go on and we'll do the next problem.
>> Douglas: Write a function addm that adds two m objects and returns an m object. So you can imagine we could have a regulatory requirement that not only do we provide results, we also provide extreme detail on how we obtained the results.

[00:01:45] So this is a way to help automate that. So, if I add two m objects, I get an object where the value is the sum of the values, and the source is the concatenation of the two values, of the two sources with a plus sign and parents around them.

[00:02:08]
>> Douglas: So, if we add m3 and m4, the source will be (3 + 4). And similar thing happening with PI. Okay, so here is addm. addm takes two m objects, it returns a new m object where the value will be the sum of the two values and the string, or the source will be the concatenation of the sources.

[00:02:35] So who got something works? Did anybody do it the hard way? Yeah, first rule of object related programming, let the objects do the work. We already have a nice constructor and we want to use it because there is a chance that we might change what m does and so we want all of the instances to take advantage of that.

[00:02:55] So if you didn't get this one, write it down because we're going to need it for the next one.
>> Douglas: Okay, are we ready? So, write a function liftm that takes a binary function and a string and returns a function that acts on m objects. So we've done this before, right?

[00:03:25] If we passed the add function to liftm and also the plus string, it will make a function that works exactly like addm. And we can do the same thing passing, multiply, an asterisk or any binary function. So this will help us to automate the process of building this system of journaling arithmetic.

[00:03:48]
>> Speaker 2: Do you need to do the check on the source whether it's string or?
>> Douglas: No, if we try to concatenate it with the strings it will be force to be a string.
>> Speaker 2: Can you show the problem again?
>> Douglas: Okay, here is liftm. liftm takes a binary function and an op string, it returns a function that takes a and b, it returns a new m object where the value will be the result of the binary function on the two values, and the source will be the concatenation of the sources of the op string.

[00:04:23] So who got liftm, way to go. So, if any of you ever heard of monads? Monads, the Haskell guys talk about them all the time, you just made a monad so you can go home and tell your kids, made a monad today. He did that, all right.
>> Speaker 3: So, what is a monad?

[00:04:48]
>> Douglas: So, a monad is a thing where you can take functions and lift them up to a higher level where they can have or acquire some new capability. The Haskell community uses them because there's a trap in Haskell. Haskell is a brilliantly designed language and one of the characteristics about it is it does not allow any kind of mutation.

[00:05:12] So all functions are pure functions in the mathematical sense and that's a really interesting thing, except that if your programs have to interact with the real world, the real world is constantly mutating, right? And something like a account balance cannot be a constant, right? It's got a very and they can't even do IO in a mutable system, right?

[00:05:35] You can't have anything coming in, you can't have anything going out because nothing can ever change. So, that kind of made things practically real hard for them and they'd figure out this trick with monads which by using a higher order functions and really clever ways, they can have the appearance of mutation without actually mutating anything.

[00:05:58]
>> Douglas: But that's for another time, anyway you made one of those, so congratulations. So if you didn't write, if you didn't get this function, you should have it now cuz we're gonna use it again in just a second. So is everybody ready to move on? Okay, so here's the next problem.

[00:06:16] Modify function liftm so that the functions it produces can accept arguments that are either numbers or m objects. So to make this a little bit easier to use, you can pass in any number, you don't have to explicitly wrap it with m first. So and we'll just change liftm to do that, okay?

[00:06:39] And make it really flexible so that you can pass in a number or an m object or two m objects or two numbers, any combination will work.
>> Speaker 3: You can choose three or four arguments or
>> Douglas: No, it will take two arguments.
>> Speaker 3: One, liftm or-
>> Douglas: Or a number.

[00:06:59]
>> Speaker 3: Or a number, okay.
>> Douglas: Okay, here is liftm. So the change I made was in the box. I just looked at the type of the argument. And if it is a number, I call m to turn it into an m object. So who got something that works?

[00:07:18] Very good. Who did it the hard way?
>> [INAUDIBLE]
>> Douglas: Where you didn't do that. [LAUGH] Yeah, so first rule of objects.