Chapter 02: First Class Functions

    That is JavaScript 101, but worth mentioning since a quick code search on github will reveal the collective evasion, or perhaps widespread ignorance of this concept. Shall we go for a feigned example? We shall.

    Here, the function wrapper around in greeting is completely redundant. Why? Because functions are callable in JavaScript. When hi has the () at the end it will run and return a value. When it does not, it simply returns the function stored in the variable. Just to be sure, have a look yourself:

    1. hi; // name => `Hi ${name}`
    2. hi("jonas"); // "Hi jonas"

    Since greeting is merely in turn calling hi with the very same argument, we could simply write:

    1. const greeting = hi;
    2. greeting("times"); // "Hi times"

    In other words, hi is already a function that expects one argument, why place another function around it that simply calls hi with the same bloody argument? It doesn’t make any damn sense. It’s like donning your heaviest parka in the dead of July just to blast the air and demand an ice lolly.

    It is obnoxiously verbose and, as it happens, bad practice to surround a function with another function merely to delay evaluation (we’ll see why in a moment, but it has to do with maintenance)

    A solid understanding of this is critical before moving on, so let’s examine a few more fun examples excavated from the library of npm packages.

    1. // ignorant
    2. const getServerStuff = callback => ajaxCall(json => callback(json));
    3. // enlightened
    4. const getServerStuff = ajaxCall;

    And that, folks, is how it is done. Once more so that we understand why I’m being so persistent.

    1. const BlogController = {
    2. index(posts) { return Views.index(posts); },
    3. create(attrs) { return Db.create(attrs); },
    4. update(post, attrs) { return Db.update(post, attrs); },
    5. destroy(post) { return Db.destroy(post); },
    6. };

    This ridiculous controller is 99% fluff. We could either rewrite it as:

    1. const BlogController = {
    2. index: Views.index,
    3. show: Views.show,
    4. create: Db.create,
    5. update: Db.update,
    6. destroy: Db.destroy,
    7. };

    … or scrap it altogether since it does nothing more than just bundle our Views and Db together.

    Why Favor First Class?

    Okay, let’s get down to the reasons to favor first class functions. As we saw in the getServerStuff and BlogController examples, it’s easy to add layers of indirection that provide no added value and only increase the amount of redundant code to maintain and search through.

    In addition, if such a needlessly wrapped function must be changed, we must also need to change our wrapper function as well.

    1. httpGet('/post/2', json => renderPost(json));

    If httpGet were to change to send a possible err, we would need to go back and change the “glue”.

    1. // renderPost is called from within httpGet with however many arguments it wants

    Besides the removal of unnecessary functions, we must name and reference arguments. Names are a bit of an issue, you see. We have potential misnomers - especially as the codebase ages and requirements change.

    Having multiple names for the same concept is a common source of confusion in projects. There is also the issue of generic code. For instance, these two functions do exactly the same thing, but one feels infinitely more general and reusable:

    1. const validArticles = articles =>
    2. articles.filter(article => article !== null && article !== undefined),
    3. // vastly more relevant for future projects
    4. const compact = xs => xs.filter(x => x !== null && x !== undefined);

    By using specific naming, we’ve seemingly tied ourselves to specific data (in this case articles). This happens quite a bit and is a source of much reinvention.

    I must mention that, just like with Object-Oriented code, you must be aware of this coming to bite you in the jugular. If an underlying function uses this and we call it first class, we are subject to this leaky abstraction’s wrath.

    1. const fs = require('fs');
    2. // scary
    3. fs.readFile('freaky_friday.txt', Db.save);
    4. // less so
    5. fs.readFile('freaky_friday.txt', Db.save.bind(Db));

    Having been bound to itself, the Db is free to access its prototypical garbage code. I avoid using this like a dirty nappy. There’s really no need when writing functional code. However, when interfacing with other libraries, you might have to acquiesce to the mad world around us.

    Some will argue that this is necessary for optimizing speed. If you are the micro-optimization sort, please close this book. If you cannot get your money back, perhaps you can exchange it for something more fiddly.