Richard Feynman, the Nobel Prize-winning physicist, developed an interest in biology while he was a graduate student at Princeton. He started attending a course in cell physiology, which required him to report on papers assigned to him. One such paper was about measuring the voltages generated by the nerves in cats:

I began to read the paper. It kept talking about extensors and flexors, the gastrocnemius muscle, and so on. This and that muscle were named, but I hadn’t the foggiest idea of where they were located in relation to the nerves or to the cat. So I went to the librarian in the biology section and asked her if she could find me a map of the cat.

“A map of the cat, sir?” she asked, horrified. “You mean a zoological chart!” From then on there were rumors about some dumb biology graduate student who was looking for a “map of the cat.”

In the software world, we don’t have as many complicated terms as there are in biology, but we aren’t completely immune to giving complex-sounding names to what should be simple concepts – some of us even enjoy getting pedantic about them. Here are some of my favorites, with examples in JavaScript:


Dependency Injection

When you pass objects as arguments to an object, it’s called dependency injection. Yes, that’s all there is to it.

The following constructor function can be used to generate UserService objects with a logger dependency. The dependency can be injected from the outside, which allows the use of different logging libraries.

var UserService = function (logger) {
    this.create = (firstName, lastName) => {
        let getFullName = () => firstName + ' ' + lastName;
        logger.info('Created User:', getFullName());
        return { firstName, lastName, getFullName };
    };
};

var myUserService = new UserService(console);
var newUser = myUserService.create('Katniss', 'Everdeen');
// [INFO] Created User: Katniss Everdeen

Factory Method

Despite the lofty name, a factory method just returns an object.

var userService = {
    create: (firstName, lastName) => {
        let getFullName = () => firstName + ' ' + lastName;
        return { firstName, lastName, getFullName };
    },
};

var newUser = userService.create('Asuka', 'Langley');
console.log(newUser.getFullName());
// Prints Asuka Langley

Higher-Order Function

A function that returns a function or takes other functions as arguments is called a higher-order function.

Most popular programming languages natively support higher-order functions, or added support for them.

In the code below, _.pickBy passes each property in the collection to the provided functions (_.isNumber or _.isString), and if those functions return true, it “picks” the corresponding properties from the collection.

const _ = require('lodash');
const collection = {'a': 1, 'b': '2', 'c': 3};

console.log(_.pickBy(collection, _.isNumber));
// { 'a': 1, 'c': 3 }

console.log(_.pickBy(collection, _.isString));
// { b: '2' }

Idempotence

A function is called “idempotent” if multiple calls to the function have the same effect on the program state as a single call. In other words, no matter how many times you call the function with the same arguments, the program state will not change after the first call.

The following function updates the status of a message with the given id in the database. The program state will not change after the first call. So, this function is idempotent.

// (...)
async function updateMessageStatus(id, status) {
    return db('message').update({ status }).where({ id });
}

await updateMessageStatus(1, 'read');
await updateMessageStatus(1, 'read');
await updateMessageStatus(1, 'read');
// The message #1's status will always be 'read'.

Immutability

All variable assignments are final. Once you assign a value to a variable, you aren’t allowed to change it in any way.

In the example below, JavaScript’s native array sort method sorts an array in place, replacing the values of the original array. Lodash’s sortBy method, on the other hand, doesn’t mutate the original array, and returns a new array instead. It’s good programming practice to avoid changing variable values whenever you can even if the programming language you use only has partial immutability support like JavaScript.

const _ = require('lodash');

const mutableElements = ['earth', 'water', 'air', 'fire'];
mutableElements.sort();
console.log(mutableElements);
// [ 'air', 'earth', 'fire', 'water' ]

const immutableElements = ['earth', 'water', 'air', 'fire'];
sortedImmutableElements = _.sortBy(immutableElements);
console.log(immutableElements, sortedImmutableElements);
// [ 'earth', 'water', 'air', 'fire' ] [ 'air', 'earth', 'fire', 'water' ]

Memoization

As a form of caching, a memoized function “remembers” the result it has previously returned for a given set of inputs. Subsequent calls with the same inputs return the remembered result rather than recalculating it.

Lodash has a convenient memoize method that can be used to turn any function into a memoized function:

const _ = require('lodash');
// (...)
const memoizedSlowFunction = _.memoize(slowFunction, (...args) => JSON.stringify(args));

That’s all for now. Let me know what your favorite complex-sounding yet simple programming terms are.


Related: