dogear

enter for all results · esc to close

Hey Underscore, You're Doing It Wrong!

youtube.comvideo

transcript

[Music] okay um I'm going to get started because it's the last Talk of the day everybody probably wants to go get a drink I want to go get a drink is there after parties does anybody know all right cool thank somebody grab me and take me to one um so you can yell at me for this talk so um this talk I originally wanted the talk about um lenses and traversible um yeah but it turned out that um you know I've given a couple similar talks and if you've seen um uh me talk at HTML 5 Dev comp before I've spoken about Point free and um type classes and this is kind of a mixture of all that I don't think I could have uh written a talk about anything else because it's 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 um pretty much going to talk about uh Point free programming and type classes all in the context of underscore um so yeah and I'm going to bash underscore like crazy you guys not really not so okay so I I do love underscore I think it's great um so I'm not I'm not here to make fun of it or say it's terrible or be like low Dash rules and you know it doesn't work on node and things like that um so uh I am here to talk about uh functional programming and uh I think that underscore does a terrible job of of saying functional you know it says it's functional but it's not really um when you compare it to a real functional language um 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 but that's what you know I think the perception of functional program is um and it's getting better and better every year uh but underscore is marketing themselves saying that they have uh these these functions um and I want to examine that and kind of take a close look at what you would really do uh and compare that to what underscore is doing um so we could see what turns out you know it can be a beautiful Paradigm all right so the agenda is currying composition funs and random stuff um so if you already know all this stuff I won't be offended if you leave we're going to go over it okay so currying um I just put that in there to wake you guys up because it's like the last Talk of the day and it's really exciting background uh so currying is just a function that takes uh keeps returning a new function until it gets all its arguments um and we can look at that a little bit closer here so with this function add um I should point out these type signatures are just comments um um we've been working on a type parser but haven't gotten too far so uh with ADD uh we take X and we return a new function that takes the Y and then we add them together and uh you can call it we have add three and when we call add with three we 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 with five and get eight so it's like it made us a new function uh we just gave it an argument and we got a new function back um and then we have this like weird butt looking thing if we try to call it all together and that's not cool um so wujs has an awesome uh function called autoc Curry and in autoc curry you basically you can just keep throwing arguments at a function and it'll just keep returning you a function uh until it gets all its arguments so you can see there in the bottom they're just like parentheses and you know any combination you can think of and you still get a function back until it gets all its arguments uh so we've just stolen that function and extended the function prototype with it uh so now um with uh add you can just slap Auto Curry at the end and when we call add three there uh we get a new function back that's just waiting for its last argument and it works just like before um except we don't have that weird but looking thing it's just you can call it all together so awesome um oh I should also say just raise your hand or walk up to the mic if you have any questions um and if you're taking the class in a couple days you'll probably see a couple of these slides over and over again so um but they'll be way more in depth okay so here's another example um full name full name takes uh three arguments here so we can call it with Hunter S Thompson and we get the name out um or we can call it just with the first um and so we get this new function called Bill something uh and that's waiting for its middle and last and if we give it that we get Bill Cosby out so um and here's another one we can call Bill something with just the middle name and uh we'll get Bill Clinton if we give it the last so you can pretty much keep giving it arguments peace meal if you want um this is 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 here's a function called modulo uh and if you've ever used modulo before um you know you pretty much you're going to call it with two I think that's what I do um so we can make a new function down there called is odd just by partially applying modulo with the number two and it comes out with zero if it's uh even and one if it's odd so it's true or false uh so that's 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 filter and uh all it's doing is wrapping the native filter uh but uh if we call it with is OD you know it runs and if we partially apply it with is OD we get a whole new function back uh and uh that's pretty useful it always get the odd odd numbers out of the array um 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 a third function out of that that's really useful so um this stuff is you know you're building new functions by giving functions arguments so let's look at an example of that and here's where we're going to examine the underscore way um so let's take a second to digest this so you have uh we're going to call this with first two letters here um or that's our function name and it'll just run through an array and return us the first two letters uh back can everybody see the comment to out one is that cool um so looking at this we've got a function that takes words we're going to map over those words and for every word uh we're going to grab the first two uh so I don't know uh in underscore the two is optional but we're going to pretend it's not here so we uh we can rewrite this in a way more functional way um let's leave the top one for reference there so here uh if we if we just examine this um if if if this function took its arguments in the other order we could partially apply it with two and that'd be pretty useful uh 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 wrapper here since it is a function waiting waiting for a word so does that make sense you guys with me we've just flipped the arguments and now this is a function since it's partially applied it'll just get each of these words and run and actually it turns out that map uh if we flip this then this would be a function these words and these words kind of match up and we can just 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 curring and partial application thing if underscore 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 we don't need letters there um so we're just going to I know map the first two here and so I could I could look at this and say you know I've got words words word word and I've got this whole ceremony around here um I don't even really need any of that I could just kind of call this in line to be honest it reads really well to me um so map the first two of these things and that'll work with anything so there's just an example probably kind of straw Manish but I just wanted to show you guys if you know underscore was a little bit more functional we could do that so um let's give us a point here on our normal functional style here um for for being able to remove all the data and be completely data generic there so it's reusable uh and let's actually get another Point um just to drive it home that uh you know there's way less code on the screen so it's more maintainable uh and third just because it didn't even need to exist in the first place um all right so underscores API prevents you from currying because the arguments are backwards um so that's kind of a bummer um so yeah there's currying it's got uh you can make generic functions it's like a it's like a little function Factory and uh you can get pretty pretty tur and concise with your definitions uh and it's good for composition which we're about to talk about uh does anybody have any questions about that before I go on because it's kind of important all right cool all right so composition um composition is uh let's see here well it's in underscore so that's great underscore has compose um and how many here do you guys use compose here show of hands how many people use compose all right we've got almost a hand hey all right like four uh how many people here use chain can you raise your hand if you use chain y like everybody all right um well uh yeah chain is mentioned like so much throughout the documentation and compose is mentioned in like the release notes and where it's defined um so let's kind of go over what compose is um so here uh you're pretty much going to stick two functions together to get a new function uh you're just composing them and it'll run both functions right to left let's look at that a little closer here uh so if you want to write a really really terribly inefficient uh way to get the last element in an array uh you could do something like this so we get uh this last function that takes X's that's our array and we're going to reverse them and grab the first one uh so that'll be a good way to get the last um but we can write that in another way we could write it like this uh which is just the composition of reverse and first and there's two uh well let's see how that works real quick boom um so we get the uh last element because it reverses it and then uh grabs the first one so it almost runs right to left passing the output of one function into the input of the next um and you can use more than two functions but uh we'll keep it simple and stick with two uh so there's there's some key differences here um in last on the the top version uh we actually uh mention X's of course in a different way so we're referring to arguments and data in that one and the one under it we're not at all we're just saying glue these two functions together uh 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 read uh this Top Line first and then the next line um but in our comp composed version It's a declarative it just says all right well you know some other process is going to handle this um so we're not going to bake in order evaluation um even though we know it goes right to left and it passes the output in the next JavaScript is like okay something else is going to handle this uh and it's it's a way more declarative higher level way of programming uh leads to things like parallelization and stuff like that if that's a word all right so here's another example uh just so we can wrap our heads around compose um so we have this word count word count function uh takes a string it splits on the spaces and then we're going to grab the length um and so it'll tell us the uh length of the words and it's the same way to do it now notice here uh we're going to partially apply split so uh split takes the spaces and it's still waiting for its string and so when we call word c with the string that finishes split and runs it and then the output of split goes into length uh so partial application currying um you know a curried function can be partially applied uh they kind of play together with composition because because uh you want to just kind of make it so your your data flows through this this kind of chain of functions so it's like chain but backwards uh and we don't have to wrap and unwrap data explicitly um so uh here's a here's a cool example of us um you're actually able to uh unest functions with it because it's going to call replace first then comment create well if you compose them it'll call the right one and then the left one so it kind of cleans up nesting to which I thought was cool to show all right uh so here it goes category Theory shout out to John Bender so um there's the in acccurate uh definition of what category theory is it's a it's basically a mathematics around uh center around transforming values is the way I would say it in a in the terms that I understand so we've got uh a couple of uh here's an example all right so these two circles on the left you the one on the left one in the middle they're both you know type A that's type person in this example and the last one is the type B which is uh I guess it's like breakfast foods um and gnf are functions so if G andf are pure functions every time I call G with John I'll get Mary like every time no matter what every time I call G with Mary I get John uh so you're just kind of connecting the dots there and if if I call uh you know G then f um with Mary I'm just going to get eggs you can just kind of follow the the way the lines go and we say we can just compose those uh and we can just cut out the middleman uh 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 dayto day and this is that like math is and programming stop using 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 uh yeah that little dot there should have mentioned is the composition operator uh and this stuff can get really complex uh but it's really just connecting the dots at the end of the day uh and you know there's there's some cool stuff down at the bottom it's demonstrating associativity uh where it doesn't matter if you group the gnf um or the g& H first uh you're always going to get the same results uh so that's pretty cool um so let's look at an example of composition let's see here okay so we're going to compare it against underscores chain because I think that's the deao way to do this and everybody seems to use chain so um let's let's take a look at this compared to the composed version of it so we're going to redefine sorted phones here and we're going to say all right well chain just wraps our users uh so that we can call Dot on it because we love calling dot on things and value just unwraps it well so the only important stuff is right here really so let's grab that um I'm just going to compose and since it's backwards we're going to compose the sort by uh and then the map I know I should learn B all right so there we go um now that's a little bit off the screen on mine but you can see it's uh that's we're done that's it uh we don't need the you know the function wrapper and all that stuff I should have left it for uh reference but uh 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 going to call Dot on it why don't we make a DOT function call that dot we'll use our Fancy Auto Curry here and that's just going to take a property and an object and we'll just use the bracket so um there we go so now we can actually just call Dot on phone and Dot on our sign up date that kind of cleans it up quite a bit feel like Bob Ross up here or something there we go isn't that lovely isn't that a beautiful beautiful way to clean this up thank you thank you uh so yeah so there's there's a composition and it kind of gets rid of the wrapping and unwrapping and the ceremony of the functions uh you can see all this extra stuff is gone so uh let's let's get back to our lovely pointing system um so we were at three to zero we're going to give it another point for being uh completely uh 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 peek here uh we've got this is kind of programming in a declarative almost like a formula uh we're switching our mentality from you know the uh sequence of events back to this kind of we can we can actually derive properties from that and I think that's really important and so uh let's give us another point for that guy um and another one oh I was I was going to give me another one but oh well all right so this is what this is what our code at luur uh looks like that's where I work we're always hiring come find me if you want to write this crazy stuff um and almost everything is using compose uh so I just wanted to point that out like it's a really you know it's a Cornerstone of of what we're doing and um this stuff really works this is straight up production code um poor clients right but um here we go okay so underscore promotes promotes chain as the function of choice and uh you know a lot of people tend to use that over uh composition which is a shame because composition has a whole math backing it and uh you know pretty powerful okay composition so you build new functions from other ones uh you can have generic programs uh it's really high level coding it's you know totally declarative uh not really specifying sequence and you got the math backing it okay onto 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 uh can we compare performance um I'd love for somebody to like do some serious benchmarks I I don't care about performance so I've just been writing code ignorantly and just delivering it was that yeah but it's it's totally I mean it's been working fine for us and and I haven't had any real problems so up can I do what in JavaScript oh no you can't do tailor recursion U but we're we're using a set of uh you know abstract functions that don't really I mean they might wrap Loops or something in the background but we're not doing explicit tailor call recursion um and I don't think there's a need to do that I think you can use uh you know patterns to capture the recursion um or higher order functions all right into the funs okay so um this all right who who knows how to solve this problem this is you're trying to call it plus one you have an array it't wants 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 want to you want to run over you want to iterate over the list um or did you say with list we oh we lift oh yeah that's way better okay well you're you're way too advanced all right so anyway we're going to iterate over this uh array um and we could just we could just map map the function over it and we get a four back uh so so uh I know a lot of people probably have done this you know you guys use map right who uses map anybody all right great awesome so we're all using map and map's great uh and and that solves this problem well if you look at it a little bit closer yes it's like we are lifting this plus one into the array uh if you look over at the kind of grade 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 uh and if we remove the syntactic sugar which uh I just realized that that's probably not going to work but let's pretend it does uh 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 uh you know it's the same thing so could we do this with any object let's see is map more abstract than just working on arrays and we certainly can uh so let's let's talk about that all right so how would it work well if you wanted to map aun function over my object what it would probably happen is it would kind of take what's out you know from inside my object and pass it into the function uh and I could run any function uh 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 uh and that's 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 function on it and close it back up so let's see what this looks like um a little closer so we're going to add you know add one to that three there um and if my my object is just a Constructor um you know we can and we just arbitrarily pick Val just to refer to the value inside it um well if we Define map for it it would look just like the the comment up there we're just going to run the function over the Val so uh this is kind of a distinct difference of how we treat um types in functional programming from the objects uh we're really going to look at you know the objects as containers or contexts for our values uh and then we can use them to dynamically dispatch our functions on them uh so we're going to look at this a little bit closer uh but basically uh we get to Define map on anything uh and by defining map on a object that object becomes a functor um all it is is a interfaces you know if you define map you have a functor okay uh so let's look at some actual useful practic applications of this um so up here we have our our friend maybe uh and the very top line there we're going to map plus one over our maybe and it's just going to add one to it and uh 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 um I might have this value or I might not have this value um 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 uh it's basically uh the null check but abstracted into a funter so if you have an OB or if you have a value let say a number or an object or anything and you put it inside of maybe uh you basically are forced 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 me um we'll look at that a little bit more uh so here's another one this is a either and uh the way either works is it kind of takes two parameters one the one on the left would be its its first parameter would be its uh default value and its second one is is the value that we're going to use so um if it's there so the Top Line there we're going to map plus one over that either and because it has that that second value it's going to use that one so we get either one and three because it added one to that two and then on the second line uh since it doesn't have its its value uh on the right it's going to just use its default its first argument you guys see that is that being kind of confusing no all right so if you if you look at either as a left and a right and you call its left argument it's default and Its Right is the one that's going to get uh given to it it'll actually use the right one if it has it and it won't if it it'll just use the default so it's an abstraction over default values almost or you could use it to do pure uh error checking and stuff but this is kind of how you'd Implement that you'd say hey if I have my right value uh just run the function on it uh and if I don't run it on the left value and so I get defaults um so I also wanted to point out there's all this promise stuff going on and everybody's freaking out about promises uh well if you just suggested that um promises are funs and all you have to do is map something over it um 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 this but it's pretty kickass 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 a unified API uh yes okay uh so let's look at an example here um all right it's 526 let's make make this happen let's make this count all right so here um we're gonna get some random ass div up here and uh we've got our function let's or our program let's look at this so update greeting HTML uh is going to take the current user we're going to call 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 it's pretty cool um and uh then we're going to concat welcome to that so you you end up with something like you know uh welcome Bob so that's a pretty cool thing and that it sets the HTML of our div after you get that string uh so what happens when we don't have a current user uh the user isn't logged in yet uh well you know how do you even null check up here we just saw that with this thing called maybe uh so let's let's say I'm going to put my uh current user in a maybe and I actually can't run this you know this function on uh my maybe anymore it doesn't take a maybe it takes a user uh so what I have to do is map over it so let's just map this function over that and I'm done uh and none of my program changed um and that's pretty awesome right uh so so all I've done is say I don't know if I have this view user or not let's just wrap it on maybe and map over it uh and let's say our boss comes back and he's like you you guys it's missing the whole welcome Banner you know if they're not logged in it doesn't say anything we could say well why don't we use either we'll say either and we'll just make some kind of you know blankie there we go and now it says welcome blankie uh so that's that's you know we've changed the value uh going into our app this is the calling code this this is our app up here you know from here to there uh and this is just the the caller there so uh and notice that this doesn't mention 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 them and we're not really making any references uh to it and now this data that doesn't exist in our app is getting wrapped and making our app work differently how crazy is that that's like you know really powerful so uh just wanted to point that out and if you know this user wasn't there yet let's say they're 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 promises in there sound cool all right um so there's that uh let's give us more points and do we get to eight no we don't get to eight 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 no it's not the native map uh so it's funny that it does that check and if it has a map it actually has to map uh match the native one so uh if you look at the map defined in underscore it's going to work on arguments objects an array uh but you know we'd have to get in there and mess with it to change it and here um you know it's just a funter interface I should be able to Define map uh as a funter so that's not very functional at all that's it's a bummer um all right so that's uh funter and it's not just map um there's reduce there's compose even uh there's a type class for that you can uh do all sorts of great stuff um and uh let's see you've got um uh there's formulas associated with map that you can drive and use and the whole funter laws uh and that Dynamic Tye safety we were talking about um if I know a Valu is going into my app and it may or may not be there or it'll eventually be there in the case of a promise I could just wrap that in a 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 over it and that's crazy awesome that's 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 more um all right uh that's pretty much my talk so in conclusion um I'm clocking in pretty early here it gives us some time for talks um so in conclusion um I was going to say a thing or two about uh you know I think underscore could be a lot more functional and uh we do love it we do use it I you know I think there's other libraries that are just as good but um you know it's great to have a standard and uh I wish we had a standard uh library that we could use for functional program in uh and we started one called score under just to be cheeky because it reverses the arguments anyway um I'll uh yeah so if you check out luer GitHub um there should be a score under there if there's not I'll put it up tonight um but I was hoping we'd get some more open- Source effort because uh I think you know next time I'd love to talk about traversible and lenses and uh you know I think this point free and these type class talks are great and and I hope more people get into it um 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 um so does anybody have any questions or just want to shoot the crap because we got some time what's up okay so like what what should the API be if you were going to create a oh that's a really good question um as as a matter of fact uh 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 um and so we found ourselves wrapping the entire array uh built-in array stuff and string stuff and um all it does is auto Curry and put its argument last it's array or string last uh and it works fine I mean it might be terribly unperformed but it might I mean it seems to be all right for me uh so uh I shouldn't be saying these things um no it's it's been fine 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 so it's it's really cool we usually uh make mobile apps so you can uh do that on that so uh yeah I would to answer your question about uh what kind of functions would you like to see I think I think just the few uh standard you know like map filter reduce and and things like that like those those are great and um the array and string uh extensions to be able to program uh functionally and uh I'll compose that works correctly because the order of evaluation in JavaScript it kind of messes up a a formula or two for you uh even though it's assoc associative you can group as many uh functions as you want in side compose uh but it doesn't actually evaluate them in the right order when you give it multiple arguments and stuff so that's interesting oh so um I originally actually started uh doing score under by taking underscore running through each to the functions flipping the arguments and calling autoc Curry on them and uh that was that was kind of a I thought it would be cool because under underscore could keep updating and it would just like change it um but uh then we ended up using low Dash and tweaking that and now we're just kind of uh I don't know where it is it's out there uh but the I don't think it's more than than the normal Library just all we did was get in there and mess with low Dash so it's the same size as low dash at this point um I love that I'm talking about low Dash even though it's an underscore talk all right um so is anybody going to that class on Wednesday all right cool hey what's going on how did oh man I gotta talk to you after this did you have a question over there that's a good question you know what I haven't T I should I should uh totally troll him I mean not no uh I think the thing is that you know in in JavaScript you're going to get these like it looks right to put your your um you know function 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 objectoriented you know like it's not it's not functional you know this is so I mean maybe it is I guess it is technically but I think it can be a lot better is all I'm saying and so I I should write but I think a lot of people would probably be like currying is too confusing without type signatures which is why we add type signatures all the time in comments um 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 got so far anybody else all right I'll see you guys later thank you [Applause] [Music]

from
Talks, Functional Programming
added
2026-10-10
likes
0

Talks › Categories > Web Development: “by Brian Lonsdorf (HTML5 Dev Conf 2015) [36:30]”

Functional Programming › Resources > Videos: “Underscore.js claims to be a functional programming library, but is it really?”