Waiting..
Auto Scroll
Sync
Top
Bottom
Select text to annotate, Click play in YouTube to begin
00:00:00
[Music] okay I'm gonna get started because it's the last talk of the day everybody probably wants to go get a drink I want
00:00:15
to go get a drink is there after parties does anybody know all right cool somebody grab me and take me to one so you can yell at me for this talk so um
00:00:26
this talk I originally wanted to talk about lenses and traversable yeah but it turned out that um you know I've given a couple similar talks and if you've seen
00:00:40
me talk at html5 Devcon before if I've spoken about point free and type classes and this is kind of a mixture of all that I don't think I could have written to talk about anything else because it's
00:00:52
people are still trying to get their heads wrapped around this and and I guess I am too and I don't want to go too far without hitting the basics so pretty much gonna talk about point free
00:01:05
programming and type classes all in the context of underscore so yeah and I'm gonna bash underscore like crazy you guys not really it's okay so I do love
00:01:19
underscore I think it's great so I'm not I'm not here to make fun of it or say it's terrible or be like lodash rules and you know it doesn't work on note and things like that so I am here to talk
00:01:31
about functional programming and I think that underscored does a terrible job of saying functional you know it says it's functional but it's not really when you
00:01:43
compare it to a real functional language and you know I'll read blog posts all the time on things like oh yeah here's the functional way this means I'm passing arguments around and I'm really verbose and it's basically procedural
00:01:56
but that's what you know I think the perception of functional programming is and it's getting better and better every year but underscore is marketing themselves saying that they have these these functions
00:02:09
and I want to examine that and kind of take a close look at what you would really do and compare that to what underscore is doing so we could see what it turns out you know it can be a beautiful paradigm alright so the agenda
00:02:21
is currying composition functors and random stuff so if you already know all this stuff I won't be offended if you leave we're gonna go over it okay so Kareem I just put that in there to
00:02:35
wake you guys up because it's like the last talk of the day and it's really exciting background so occurring is just a function that takes keeps returning a new function until it gets all its
00:02:47
arguments and we could look at that a little bit closer here so with this function add I should point out these type signatures are just comments we've
00:03:00
been working on a type parser but haven't gotten too far so with ADD we take X and we return a new function that takes the Y and then we add them together and you can call it we have add
00:03:13
three and when we call add with three we say that's partially applying it with three then we get a new function back and that function we can call with four we'll get seven and we can call it again
00:03:26
with five and get eight so it's like it made us a new function we just gave it an argument and we got a new function back and then we have this like weird but looking thing if we try to call it
00:03:38
all together and that's not cool so woojae s has an awesome function called Auto curry and in Auto curry you basically you can just keep throwing
00:03:50
arguments out of function and it'll just keep returning you a function until it gets all its arguments so you can see there in the bottom there just like parentheses and you know any combination you can think of and you still get a
00:04:02
function back until it gets all its arguments so we've just stolen that function and extended the function prototype with it so now with add you can just slap auto curry at the end and
00:04:15
when we call add three there we get a new function back that's just waiting for its last argument and it works just like before except we don't have that weird but looking thing it's just you can call it
00:04:27
all together so awesome oh I should also say just raise your hand or walk up to the mic if you have any questions and if you're taking that class in a couple days you'll probably see a couple of these slides over and over again so but there'll be way more
00:04:41
in depth ok so here's another example full name full name takes three arguments here so we can call it with Hunter s Thompson and we get the name out or we can call it just with the
00:04:55
first and so we get this new function called Bill something and that's waiting for its middle and last and if we give it that we get Bill Cosby out so and here's another one we can call Bill something with just the middle name and
00:05:08
we'll get Bill Clinton if we give it the last so you can pretty much keep giving it arguments piecemeal if you want there's just an example of like how you can use it to get a feel for it so why would we do this well all right so
00:05:22
here's a function called modulo and if you've ever used modulo before you know you pretty much you're going to call it with - I think that's what I do so we can make a new function down there
00:05:36
called is odd just by partially applying modulo with the number two and it comes out with zero it's even and one if it's odd so it's true or false so that's
00:05:49
that's a pretty cool application of it we've got a new function that's pretty useful just by partially applying modulo and here's another example we've got this function filter and all it's doing
00:06:01
is wrapping the native filter but if we call it with is odd you know it runs and if we partially apply it with is odd we've got a whole new function back and that's pretty useful it always get the
00:06:15
odd odd numbers out of in the array but what's crazy here is is odd is partially applied itself right so you have a partially applied is odd with a partially applied filter and we've got a third function out of that that's really
00:06:27
useful so this stuff is you know you're building new functions by give functions arguments so let's look at an example of that and here's where we're gonna examine the underscore way so
00:06:41
let's take a second to digest this so you have a we're gonna call this with first two letters here that's our function name and it'll just run through an array and return us the first two
00:06:54
letters back can everybody see the commented out one is that cool so looking at this we've got a function that takes words we're gonna map over those words and for every word we're
00:07:07
gonna grab the first two so I don't know an underscore the two is optional but we're gonna pretend it's not here so we uh we can rewrite this in a way more functional way
00:07:20
let's leave the top one for reference there so here if we if we just examine this if if this function took its arguments in the other order we could
00:07:33
partially apply it with two and that'd be pretty useful because then it'd be a function just waiting for its word and if we just take that word off we could put it in place of this whole function
00:07:46
wrapper here since it is a function waiting and waiting for a word so it's that makes sense you guys with me we've just flipped the arguments and now this is a function since it's partially
00:07:58
applied it'll just get each of these words and run and actually it turns out that map if we flip this then this would be a function these words and these words kind of match up and we can just
00:08:11
take this off now it's a function waiting for words so there we go and that's all we needed so um it's it's pretty cool with this currying and partial application thing if underscore
00:08:24
did that we could have just done this and it's pretty expressive we could say hey I just want to map the first two and turns out it's not specific to letters at all and we don't need letters there so we're just gonna you know map the
00:08:37
first two here and so I could I could look at this and say you know I've got words where Birds word word and I've got this whole ceremony around here I don't even really need any of that I could just kind of
00:08:51
call this in line to be honest it reads really well to me so map the first two of these things and that'll work with anything so there's just an example probably kind of strong mannish but I
00:09:04
just wanted to show you guys if you know underscore was a little bit more functional we could do that so let's give us a point here on our normal functional style here for for being able
00:09:17
to remove all the data and be completely data generic there so it's reusable and let's actually get another point just to drive it home that you know there's way less code on the screen so it's more
00:09:30
maintainable and there just because it didn't even need to exist in the first place all right so underscores API prevents you from currying because the arguments
00:09:41
are backwards so that's kind of a bummer so yeah there's currying it's got you can make generic functions it's like a like a little function Factory and you can get pretty pretty terse and concise
00:09:53
with your definitions and it's good for a composition which we're about to talk about does anybody have any questions about that before I go on because it's kind of important all right cool all
00:10:06
right so composition composition is let's see here well it's in underscore so that's great underscore has composed and how many here do you guys see use compose here show of hands how many
00:10:19
people use compose all right we've got almost a hand Hey how many people here use chain can you raise your hand if you use chain hey like everybody alright
00:10:32
well yeah chain is mentioned like so much throughout the documentation and composes mentioned in like the release notes in where it's defined so let's kind of go over what compose is so here
00:10:45
you're pretty much gonna stick two functions together to get a new function you're just composing them and it'll run both functions right to left let's look at that a little so here so if you want to write a really
00:10:59
really terribly inefficient way to get the last element in an array you could do something like this so we get this last function that takes X's that's our array and we're gonna reverse them and
00:11:11
grab the first one so that'll be a good way to get the last but we can write that in another way we could write it like this which is just the composition of reverse and first and there's two
00:11:25
well let's see how it works real quick boom so we get the last element because it reversed sit and then grabs the first one so it almost runs right to left passing the output of one function into
00:11:38
the input of the next and you can use more than two functions but we'll keep it simple and stick with two so there's there's some key differences here in
00:11:49
last on the the top version we actually mention X's of course in a different way so we're referring to arguments and data and that one and the one under it were not at all we're just saying glue these
00:12:02
two functions together and also in the top one we're specifying we're actually baking in an order of evaluation for JavaScript JavaScript can't evaluate it in a different way it's like I have to
00:12:15
read this top line first and then the next line but in our composed version it's a declarative it just says alright well you know some other process is going to handle this so we're not gonna
00:12:28
bake in order of evaluation even though we know it goes right to left and it passes the output in the next Java scripts is like okay something else is going to handle this and it's it's a way more declarative higher-level way of
00:12:40
programming leads to things like parallelization and stuff like that if that's a word all right so here's another example just so we can wrap our heads around compose so we have this
00:12:52
word couch a word count function it takes a string and splits on the spaces and then we're gonna grab the length and so it'll tell us the length of the words and it's the same way to do it
00:13:06
now notice here we're gonna partially apply split so split takes the spaces and it's still waiting for its string and so when we call word counting with the string that finishes split and runs it and then the
00:13:18
output of split goes into lengths so partial application / careening you know curried function can be partially applied they kind of play together with composition because you want to just
00:13:30
kind of make it so your your data flows through this this kind of chain of functions so it's like chain but backwards and we don't have to wrap and unwrap data explicitly so here's a
00:13:44
here's a cool example of us you're actually able to unnecessary and then
00:13:57
the left one so it kind of cleans up nesting too which I thought was cool to show our you so here it goes category theory shoutout to John bender
00:14:07
so there's been accurate definition of what category theory is it's basically a mathematics around center around transforming values the way I would say
00:14:20
it in the terms that I understand so we've got a couple of here's an example all right so these two circles on the Left you're the one on the left in the
00:14:32
middle they're both you know type a let's type person in this example and the last one is the type B which is uh I guess it's like breakfast foods and gnf
00:14:44
are functions so if Gina for pure functions every time I call G with John I'll get Mary like every time no matter what every time I called G with Mary I get John and so you're just kind of
00:14:57
connecting the dots there and if I call you know G then F with Mary I'm just gonna get eggs you can just kind of follow the way the lines go and we say we can just compose those and we can
00:15:10
just cut out the middleman and that's really useful and there's a whole set of you know formulas and and things you can look up and learn that's actually applicable day to day and this is not like math using programming stop using
00:15:23
math and programming stuff I mean it's just you know a useful guiding light that you can be like oh look at this I'm just composing these two things it's like a formula and I can use this to help me so yeah that little dot there
00:15:36
should have mentioned is the composition operator and this stuff can get really complex but it's really just connecting the dots at the end of the day and you know there's there's some cool stuff down on the bottom it's demonstrating
00:15:49
associativity or it doesn't matter if you group the G and F or the gene H first you're always going to get the same results so that's pretty cool so
00:16:01
let's look at an example of composition okay so we're gonna compare it against underscores chain because I think that's the de-facto way to do this and everybody seems to use chain so let's let's take a look at this compared to
00:16:18
the composed version of it so we're gonna redefine sorted phones here and we're gonna say alright well chain just wraps our users so that we can call dot
00:16:30
on it because we love calling dot on things and value just unwraps it well so the only important stuff is right here really let's grab that I'm just gonna
00:16:45
compose and since it's backwards we're gonna compose the sort by and then the map I should learn BIM alright so there
00:16:57
we go now that's a little bit off the screen online but you can see it's that's we're done that's it we don't need the you know the function wrapper and all that stuff I should have left it for
00:17:10
reference but what's cool is since we're doing functional programming and we could we could see that we've got a function that takes some argument and we're just calling dot phone functions and you know we're gonna called dot on
00:17:22
it why don't we make a dot function call dot will use our fancy auto curry here and that's just gonna take a property and an object and we'll just use the
00:17:35
bracket so there we go so now we can actually just called dot on phone and dot on our signup date that kind of
00:17:52
cleans it up quite a bit like Bob Ross up here or something there we go this isn't that lovely there's not a beautiful beautiful way to clean this up thank you thank you so yes
00:18:04
there's there's a composition it kind of gets rid of the wrapping and unwrapping and the ceremony of the functions you can see all this extra stuff is gone so let's let's get back to our lovely pointing system so we're at three to
00:18:18
zero we're gonna give it another point for being completely data generic once again in a different way and then um let's see let's uh if you looked at it it was actually um let's take another
00:18:31
peek here we've got it this is kind of programming in a declarative almost like a formula we're switching our mentality from you know the sequence of events back to this kind of we can we can
00:18:45
actually derive properties from that and I think that's really important and so let's give us another point for that guy and another one I was I was gonna give me another one but oh all right so this
00:18:57
is what this is what our code at looper ker looks like that's where I work we're always hiring come find me if you want to write this crazy stuff and almost everything is using compose so I just
00:19:10
wanted to point that out like it's a really insane it's a cornerstone of what we're doing and this stuff really works this is straight up production code poor clients right but here we go
00:19:22
okay so underscore notes promotes chain as the function of choice and you know a lot of people tend to use that over composition which is a shame because composition has a whole math backing it
00:19:34
you know pretty powerful okay composition so you build new functions from other ones you can have generic programs it's really high-level coding it's you know totally declarative not really specifying sequence and you got
00:19:48
the math backing you okay on to the heavy stuff take a break for a second all right are you guys still with me I know it's like five something hey what's up the question is can we compare
00:20:04
performance I'd love for somebody to do some serious benchmarks I I don't care about performance so I've just been writing code ignorant Lee insisting what was that yeah but it's it's totally I mean it's
00:20:17
been working fine for us and and I haven't had any real problems so oh no you can't do Taylor recursion but we're
00:20:28
we're using a set of a you know abstract functions that don't really I mean they might wrap loops or something in the background but we're not doing an explicit Taylor call recursion and I don't think there's a need to do that I think you can use you know patterns to
00:20:41
capture the recursion or higher-order functions all right into the functors okay so all right who knows how to solve this problem this is you're trying to
00:20:55
call it plus one you have an array a once an X but it doesn't have an X it has an array so what do we do how do we solve this yeah you wanna you want to run over and you want to iterate over
00:21:08
the list or do you say with Lisp oh we lift oh yeah that's way better okay well you're a - you're way too advanced all right so anyway we're gonna
00:21:19
iterate over this array and we could just you just map map the function over it and we get it for back so so I know a lot of people probably have done this you know you guys use map right who uses
00:21:32
map all right great awesome so we're all using map a maps great and and that solves this problem well if you look at a little bit closer yes it's like we are lifting this plus one into
00:21:45
the array if you look over at the kind of grayed out it's like we put it inside there and we're running the function on it and then it comes back out as a four and if we remove the syntactic sugar which I just realized
00:21:58
that that's probably not going to work but let's pretend it does if you give it multiple arguments it makes an array if you give it one it makes a blank one with that length but anyway so we removed the syntactic sugar and you know
00:22:11
it's the same thing so could we do this with any object let's see is map more abstract and just working on arrays and we certainly can so let's let's talk
00:22:22
about that all right so how would it work well if you wanted to map a function over my objects what probably happened is it would kind of take what's out you know from inside my object and
00:22:36
pass it into the function and I could run any function over my object and it would actually you know open it up run the function on the contents and then close it back up for me and that's
00:22:48
exactly the intuition you should have when you're thinking of map I'm going to map this function over over this object it's like I put my value in a bubble and I have to open up the bubble and run the
00:23:00
function on it and close it back up so let's see what this looks like a little closer so we're gonna add you know add one to that three there and if my object
00:23:11
is just a constructor you know we can and we just arbitrarily pick Val just to refer to the value inside it well if we define map four it would look just like the comment up there we're just gonna
00:23:24
run the function over the bell so this is kind of a distinct difference of how we treat types in functional programming from the objects we're really going to look at you know the objects as
00:23:38
containers or contexts for our values and then we can use them to dynamically dispatch our functions on them so we're gonna look at this a little bit closer but basically we get to define map on
00:23:50
anything and by defining map on object that object becomes a functor all it is is a interfaces you know if you define map you have a functor okay so let's look at
00:24:04
some actual useful practical applications of this so up here we have our our friend maybe and the very top line there we're gonna map plus one over our maybe and it's just gonna add one to
00:24:15
it and the middle line it says maybe null and it actually doesn't do anything it just ignores it and that's the behavior of maybe maybe says I might have this value or I might not have this
00:24:28
value and if I don't don't even run the function just return me the maybe back and we can just define this really easily by saying if you've got a value run it if you don't don't so that's a pretty cool thing it's
00:24:42
basically the null check but abstracted into a functor so if you have a knob or if you have a value that's a number or an object or anything and you put it inside a maybe you basically are forced
00:24:55
to map over it you can't just run your function on your value anymore it's inside the maybe so you have to map over that just like we saw with the list and that gives you some kind of like dynamic type safety that's really interesting to
00:25:07
me we'll look at that a little bit more so here's another one this is a either and the way either works is it kind of takes two parameters one the one on the left would be its its first parameter
00:25:20
would be its default value and its second one is is the value that we're gonna use so if it's there so the top line there we're gonna map +1 over that
00:25:33
either and because it has that that second value it's going to use that one so we get either 1 & 3 because it added 1 to that 2 and then on the second line since it doesn't have its its value on
00:25:46
the right it's going to just use its default its first argument you guys see that is that being kind of confusing now all right so if you if you look at it either as a left and a right and you
00:25:58
call its left argument its default and it's right is the one that's gonna get given to it it'll actually use the right one if it has it and it won't if it'll just use the default so it's an abstraction over default
00:26:10
values almost or you could use it to do pure error-checking stuff but this is kind of how you'd implement that you'd say if I have my right value just run the function on it and if I don't run it on
00:26:22
the left value and so I get defaults so I also wanted to point out there's all this promise stuff going on and everybody's freaking out about promises well if you just suggest that promises
00:26:38
are functors and all you have to do is map something over it that Ajax get posts you know if that returns a promise I'm just going to map populate table over that eventual value you know I don't really want to get too far into
00:26:49
this but it's pretty kick-ass like it's the intuition is there I don't need to learn about then and when and on and all the different libraries I can just map over it and it's the unified API yes
00:27:02
okay so let's look at an example here all right it's 526 let's make that make this happen let's make this count all right so here um
00:27:17
we're gonna get some random assitive up here and we've got our function let's a program look at this so update greeting HTML is gonna take the current user
00:27:30
we're gonna call it get greeting first because that's how compose works and that's going to pass the user into get greeting and call dot name on it you guys remember dot from the other example
00:27:41
it's pretty cool and then we're gonna concatenate sets the HTML of our div after you get that string so what happens when we don't have a current user the user isn't logged in yet well
00:28:05
you know how do you even know check up here we just saw that with this thing called maybe so let's let's say I'm gonna put my current user in a maybe and
00:28:17
I actually can't run this you know this function on a my maybe anymore it doesn't take a maybe it takes a user so what I have to do is map over it so let's just map this function over
00:28:29
that and I'm done and none of my program changed and that's pretty awesome right so so all I've done is say I don't know if I have this view user or not let's
00:28:43
just wrap it or maybe a map over it and let's say our boss comes back he's like you guys it's missing the whole Welcome banner you know if they're not logged in it doesn't say anything but we could say well why don't we use either I'll say
00:28:56
either and then we'll just make some kind of you know blankie there we go and now it says welcome blankie so that's that's you know we've changed the value
00:29:09
going into our app this is the calling code this this is our app up here you know from here to there and this is just the the caller there so and notice that this doesn't mention
00:29:22
that data you know we've been we spent half this talk just removing data from our app and just gluing functions together and partially applying and we're not really making any references to it and now this data that doesn't
00:29:35
exist in our app is getting wrapped in making our app work differently how crazy is that that's like you know really powerful so I just wanted to point that out and if you know this user wasn't there yet let's say they're
00:29:48
coming from the database and you know we've got this promise there it would work exactly the same way I just wanted to throw up promises and they're so cool so there's that let's give us more
00:30:01
points and we get to eight now I don't get okay so underscore explicitly prevents extending map it even checks to see if you've defined map on your object and then it's like now about the native map
00:30:15
so it's funny that it does that check and if it has a map it actually has to map match the native one so if you look at the map to find in underscore it's gonna work on arguments objects and arrays
00:30:28
but you know we'd have to get in there and mess with it to change it and here you know it's just a functor interface I should be able to define map as a functor so that's not very functional at all it's a bummer all
00:30:42
right so that's functors it's not just map there's reduced there's compose even there's a type class for that you can do all sorts of great stuff and let's see you've got
00:30:54
there's formulas associated with map that you can drive and use and the whole functor laws and that dynamic tape safety we were talking about if I know of values going into my app and it may
00:31:07
or may not be there or it'll eventually be there in the case of a promise I could just wrap that and uh maybe or a promise or whatever and the rest of my app is forced to deal with it because it can't get to the value without mapping
00:31:19
over it and that's crazy awesome that forces you guys to be like oh well all right let's map over this and it just works I don't I don't have to make those mistakes anymore all right that's pretty
00:31:31
much my talk so in conclusion clocking in pretty early here because some time for talks so in conclusion I was gonna say a thing or two about you know I think underscore could be a lot more
00:31:45
functional and we do love it we do use it I you know I think there's other libraries that are just as good but you know it's great to have a standard and I wish we had a standard library that we could use for functional programming and
00:31:59
we started one called score under just to be cheeky because it reverses the arguments anyway yeah so if you check out loop occurs github there should be a score under there if there's not a put it up tonight
00:32:13
but I was hoping we'd get some more open source effort because I think you know next time I'd love to talk about traversable and lenses and you know I think this point free and these type class talks are great and and I hope
00:32:26
more people get into it and I hope we build a bigger community because it's really small right now and clients are like can't believe you gave me this app this is crazy so does anybody have any
00:32:39
questions I just want to shoot the crap because we've got some time what's up okay so like what what should the API be if you were gonna create a that's a really good question um as a
00:32:57
matter of fact so so we use it's it's weird when you're programming functionally you kind of want the world to be a function like everything to be a function and so we've found ourselves wrapping the entire array built in array
00:33:12
stuff and string stuff and all it does is auto curry and put its argument last its array or string last and it works fine I mean it might be terribly unperformed but it might I mean it seems
00:33:24
to be all right for me so I shouldn't be saying these things now it's been fun it's in production code they're big clients and everybody's happy so it's no big deal and we end up with really small maintainable and parallelizable programs
00:33:38
so it's it's really cool we usually make mobile apps so you can do that on that so yeah answer your question about what kind of functions would you like to see
00:33:50
I think I think just a few standard you know like map filter reduce and things like that like those those are great and the array and string extensions to be
00:34:02
able to program functionally and a compose that works correctly because the order of evaluation in JavaScript it kind of messes up a formula or two for you even though it's associative you can
00:34:16
group as many functions as you want inside compose but it doesn't actually evaluate them in the right order when you give it multiple arguments and stuff so that's interesting
00:34:28
so I originally actually started doing score under by taking underscore running through each of the functions flipping the arguments and calling Auto Curry on him and that was that was kind of a I
00:34:41
thought it would be cool cuz underscore could keep updating and it would just like change it but uh then we ended up using lodash and tweaking that and now we're just kind of I don't know where it is it's out there put the I don't think
00:34:55
it's more than than the normal library just all we did it was get in there and mess with low - that's same sizes low - at this point I love that I'm talking about low - even though it's an underscore talk alright so is
00:35:09
anybody going to that class on Wednesday all right cool hey what's going on how did you oh man I got to talk to you after this did you have a question over there that's a good question you know
00:35:22
what I haven't I should I should totally troll him I mean not know I think the thing is that you know in JavaScript you're gonna get these like it looks right to put your your you know function
00:35:36
last like that's what looks right to people and so I think when we're like oh well this is functional and you know this is is object-oriented you know like
00:35:48
it's not it's not functional yeah this is so I mean maybe it is I guess it is technically but I think it could be a lot better as all I'm saying and so I should right but I think a lot of people would probably be like currying is too confusing without type
00:36:03
signatures which is why we add type signatures all the time in comments and I've got a thing or two to say about that but I don't want to waste too much time so but anyway I think that's all I
00:36:13
got so far anybody else all right I'll see you guys later thank you [Applause]
00:36:23
[Music]
End of transcript