

Functional JavaScript, Part 3: apply, call, and the arguments object - skiskilo
http://tech.pro/tutorial/2010/functional-javascript-part-3-apply-call-and-the-arguments-object

======
mycroft-holmes
I'm relatively new to JS and functional programming and I've found that
functional programming has been extremely difficult for me to grasp. I
eventually figure it out (so far) but it takes me _forever_ to read through
code. You return a function that has a function in that that has another
function in that and so on.

Is this normal?

~~~
lrichardson
Yes and no.

Some of this is that JavaScript is just not very well equipped to do
functional programming. For instance, the nesting of functions in JavaScript
is not only verbose to write, it also introduces a lot of noise in the code.

One pretty simple/obvious setback for JavaScript is that declaring an
anonymous function (or a lambda) entails quite a few characters. In ES6, [this
will change with the introduction of "Arrow Functions"][2], but that's not
going to be a cure-all by any means.

Languages geared more towards the functional edge will handle things like
curried higher order functions almost without you realizing it. For instance,
taking an excerpt from my next post in the series (still unpublished):

    
    
        var uncurried = function (a, b, c) {
            // do something with a, b, and c
        };
    
        var curried = function(a) {
            return function (b) {
                return function (c) {
                    // do something with a, b, and c
                };
            };
        };
    

There we have two ternary functions (3 arguments), but the first one is
uncurried (how you would expect it in javascript), and the second one is
manually written in a curried fashion.

Some programming languages, such as Haskell and OCaml, have function currying
built into the language. What that means is that, technically, __every
function is a function of one argument, and one argument only __.
Syntactically, however, they may make this restriction almost unnoticable.

For instance, in OCaml, one could write the two functions above like:

    
    
        let uncurried = fun a b c ->
            // (* do something with a, b, c *)
    
        let curried = fun a ->
            fun b ->
                fun c ->
                    // (* do something with a, b, c *)
    

The difference, however, is that in OCaml these are _exactly_ the same thing.
In OCaml, no functions have multiple arguments. However, invoking curried
functions syntactically looks the same as what one would expect invoking a
function with multiple arguments would be. To call the functions above we
would write:

    
    
        uncurried foo bar baz
        curried foo bar baz
    

Whereas in JavaScript, we have the obvious difference:

    
    
        uncurried(foo, bar, baz);
        curried(foo)(bar)(baz);
    

Many would argue that the readability of the former is much better than the
latter.

\---

Anyway, what I am trying to build up to in this series is building a set of
tools to make writing code like this a little more fluid in JavaScript than
native JavaScript would allow.

This goes back to my example in [Part 1][1], where I show an underscore
example:

    
    
        var firstTwoLetters = function(words){
            return _.map(words, function(word){
                return _.first(word, 2);
            });
        };
    

Which, the _exact_ same thing can be represented "my way" with:

    
    
        var firstTwoLetters = map(first(2));
    

I would argue that this is much more readable, and perhaps you would agree?

    
    
      [1]: http://tech.pro/tutorial/1953/functional-javascript-part-1-introduction
      [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions

~~~
thinkpad20
I think your post is a bit misleading; in the OCaml example, both functions
are curried. This would be a better juxtaposition (I'm mostly guessing at the
syntax; I'm a Haskeller).

    
    
        let uncurried = fun (foo, bar, baz) -> qux
        let curried = fun foo bar baz -> qux
    

It's a relatively small nitpick, but that's what currying means in this
instance. And really, JavaScript is the same way; a function with "multiple
arguments" is really just a function where the argument is a tuple. It's just
that syntactically, it's cleaner in JavaScript (and many other languages) to
declare and call functions with tuples.

~~~
lrichardson
I guess I didn't mean for it to be misleading, but I wrote the example like I
did on purpose to show that in OCaml, the arguments are curried by default...
that there is no need to have the `fun` keyword 3 times.

The misleading part was probably naming the first function "uncurried"... the
point of the example was to show that they were both curried.

I'll try to make this more clear in my post. Thanks.

------
vqc
I've been on a functional JS binge recently and have found
[https://leanpub.com/javascript-allonge](https://leanpub.com/javascript-
allonge) extremely helpful in explaining functional concepts and reexplaining
basic javascript concepts. I can't recommend the book enough.

~~~
lrichardson
Having read the book, I can definitely recommend it. Along with the book,
Braithwaite created [allonge.es][1], a functional js library which follows
much more closely how I would create a FP utility library in JS (versus,
something like lo-dash or underscore).

    
    
      [1]: https://github.com/raganwald/allong.es

~~~
vqc
Being a novice, what would be extremely helpful would be to see someone apply
these concepts in different parts of the stack on a real world web app.
Discussion also regarding when these concepts should not be used or are
otherwise terrible would be great.

~~~
lrichardson
That is great feedback. I am actually working on creating a "functional"
version of the 2048 game, along with my own implementation of the AI solver,
as part of this series. Kinda goofy, and maybe not a "real world" situation as
much, but should at least show the concepts being applied.

I also very much recommend this video by Brian Lonsdorf, titled "Hey
Underscore, You're Doing It Wrong!:

[https://www.youtube.com/watch?v=m3svKOdZijA](https://www.youtube.com/watch?v=m3svKOdZijA)

~~~
platz
I think Lonsdorf needs to check out PureScript
[https://github.com/purescript/purescript](https://github.com/purescript/purescript).
He's practically writing in a style like it already.

~~~
vqc
It would also be helpful to have resources regarding the type notation that he
uses. I imagine that the notation is the same regardless of the language you
use to apply it, but I'm not in a position to be sure. E.g.
[http://learnyouahaskell.com/types-and-
typeclasses](http://learnyouahaskell.com/types-and-typeclasses)

~~~
platz
Yes he's borrowing the type notation from haskell to make his intentions
clear, but of course this is only conceptual, and comments can be wrong -
you'd need something like TypeScript to actually get feedback on types.

------
lrichardson
author of the article here: this is part 3 of what will likely be a 6+ part
series... as a result, this post is still sort of "laying the foundation",
before getting to some of the "fun stuff".

In any event, would love to hear any feedback!

~~~
stankalank
I found your section on converting prototype methods into utility functions
really interesting, I found myself doing the same thing a few days ago. One
suggestion for your 'demethodize' function is to replace the prototype methods
you use with purely functional versions (AKA replace [].slice and fn.apply).
It seems kind of funky to have a function dedicated to demethodizing prototype
methods that makes use of prototype methods!

~~~
lrichardson
Yeah, I think I sometimes weave back-and-forth. I try to avoid thinking about
"micro-optimizations", but can't help myself. As I'm writing this series I'm
compiling together a small and opinionated library that uses a lot of these
concepts, and I am tending to use native methods, for loops, while loops etc.
in favor of performance....

but I should probably stop that and instead favor the clean code following the
very principles they are there to promote! One of my points was that
performance doesn't really matter here anyway.

Thanks for pointing out. I might update a couple spots.

------
jcreamer
Wow, what an amazingly detailed article. Really enjoying this series so far.

