In this article, I’m going to talk about what FP is and illustrate it with examples from the four key currents in modern JS: NodeJS, React, Angular and VueJS.

If I were to boil it down to a single sentence to answer the question “What is Functional Programming,” I’d say: FP is the discipline of using functions to the best effect to achieve clean syntax and small surface areas between loosely coupled components.

Without further ado!

First Class Functions

The notion of Functional Programming hinges on first class functions (FCF). A FCF is distinguished from a normal function use by the fact that the function is treated as a thing-in-itself, capable of standing alone and being treated independently.

This is also called functions as data. In essence, and time you create a variable for a function, pass a function as an argument, or use a function as a return value, you are using first class functions/functions as data.

Function References

A nice clean example of this is a function reference, seen below.

let myFunction = new function() { console.info("foobar!"); }

With the reference in hand, you can work with the function as a full blown member of the code. This includes invoking it, passing it as an argument, or using it as a return value. This is not true of all languages, and it creates the possibility of unique approaches to logic and design.

In JS, you can invoke it with normal syntax:

myFunction(); // outputs "foobar"

JavaScript is allowing you to define a custom function type, just like it allows you define custom object types with prototype .

Meta-Functions

Functions that make use of other functions. I’ll call them meta-functions. They are also called higher order functions.

There are two basic types that we’ll take in turn: functions as arguments (consumers) and functions that return functions (generators).

Consumers: Functions as Arguments

This is the real heart of FP. Let’s see it in action on the server. Here is a look at a route mapping in node and the express web framework.

var express = require('express');

var app = express(); app.get('/', function (req, res) {

res.send('One Love!');

});

This is some classic FP. When we call app.get() we pass in a function.

In fact, the entire idea that enabled NodeJS is the event-loop. The very core of Node’s architecture is FP: functions are handed to the engine to be offered up for execution.

Notice how the function will receive arguments from the framework ( req and res ).

“Callback”

This is often called a callback function. These have been in heavy us in JS for.. ever. This is probably the most conspicuous and important feature of FP. In short: you’ve probably been using callbacks, so you’ve probably been using FP.

Callback is a nice, obvious term: you are handing off a function that will be called back by whomever you handed it off to.

This simple seeming feature actually drives a lot of benefit for the “join points” in applications, in defining how parts of the app interact. For example, when you hand a function to the DOM in plain JS (or any framework), you are interfacing with the browser via a function callback.

“callback” is simple and obvious, but there are plenty of other complex sounding terms around the idea.

Anonymous Function

When we defined that function that was passed into Express, it was defined inline, without a variable reference to it. That is an anonymous function.

Any time you see a function definition without a reference to it, that is an anonymous function.

=> Fat Arrow Syntax

JavaScript 6 (aka ECMAScript 6) introduced a short hand for function definition. We could write the Express callback like so.

app.get('/', (req, res) => {

res.send('One Love!');

});

Notice that we’ve eliminated the function keyword. This cleaner. We can go a bit further:

app.get('/', (req, res) => res.send('One Love!') );

Now we’ve gotten rid of the curly braces also. Pretty clean. Note that if there is only one argument, you can do away with the parenthesis; if there is a return value, and you don’t have curly braces, the function will automatically return whatever it evaluates to.

Function Consumer in React.js

FP is all over the place in the front-end JS also. Here it is in React, where the callback is used to handle an event on an element:

<button onClick={function() { alert('click'); }}>

Click THIS.

</button>

Of course, we could also use the fat arrow synax:

<button onClick={ () => alert('click'); }>

Click THIS.

</button>

Anonymous Functions, Fat Arrow, and the this keyword

Besides being cleaner, the fat-arrow syntax handles the binding of this differently than normal anonymous functions.

In essence, the this keyword will be resolved to the surrounding functional context. So you could say that instead of creating a new context for itself, the fat arrow defined function will assume the context of the parent, or wrapping function. In code:

var o = {};

o.test = function(){

var standardAnon = function(){

console.log("this = " + this);

}

var fatArrow = () => console.log("this = " + this);

standardAnon();

fatArrow();

}

o.test();

Outputs:

this = [object Window]

this = [object Object]

If you look at that a couple times, the nature of this and the two kind of anonymous functions will be firmly implanted (if it wasn’t already).

Lexical “Scope”

The above behavior of the fat arrow syntax goes by that name lexical scope. This is a fancy way of saying: the context defined by the code’s words themselves.

Put another way, lexical scoping is the context found in the lines of code where the function is executed, not in a new context defined by the function.

Put a third way: if lexical scope is in effect, then the this keyword will be used for the execution of the function.

Side Note: According to JavaScript’s own naming conventions, this should be called lexical context. Context means “What is this ". Scope means “What variables are available”. Sigh.

closures

Another FP term you’ll see is closure. Closure is more of a language implementation term: It means that functional contexts are persisted until no reference to them exists.

It means that the function scope is able to be packaged up (“closed up”) and maintained beyond its own existence for the purpose of execution outside that scope.

Put another way: the lexical scope of the function lives on. For example:

foo = function(){

var closuredVar = "From the parent closure";

var bar = function(){

console.log("I can see closuredVar: " + closuredVar);

}

bar();

}

foo();

This is probably really unremarkable to a JS developer, but it is a significant language: it is smart enough to maintain the outer context for the purpose of executing the inner.

Another example of something you were probably familiar with, even if you didn’t know about the fancy word.

In this case, you may think, “This is how it should work… obviously, there is still a call out there to foo() so the language should keep the context around, including a context for the inner functions."

That is true, it is the obvious way it should work (just as in any garbage collected language, you expect any variable that still has a reference to continue living). Its just that in building the language itself, achieving that obvious behavior is non-obvious, nor trivial, to say the least, and the approach to delivering it came to be called a closure.

Working With Collections

Collections are a clear win — perhaps the most obvious and prominent case— for functional programming. By using functional arguments, dealing with collections becomes easier and more understandable.

The various array (and array-like) functions: forEach, map, filter and reduce are the stars in this story. These are built into JS’s collections, and they all take functions as arguments, and pass the individual items into that argument.

As a simple example, below is map going through an array and creating a new array with the words reversed.

let words = [“test”,”foo”,”bar”];

let reversed = words.map(x => x.split(“”).reverse().join(“”))

The real beauty of these methods is they are compact, and allow the flow of code and thought to proceed smoothly.

Fluent Programming

Another great thing about the collection API and FP in general is what goes by the name “Fluent Programming”. This is simply the ability to chain functions together, by virtue of the fact that each function returns a value that the next function can operate upon.

For instance, below, we use our map example from above, and chain it with a call to reduce . The net result is, we get a new array with reversed words from map and then a combined string from reduce.

let words = [“test”,”foo”,”bar”];

words.map(x => x.split(“”).reverse().join(“”))

.reduce((combined, x) => combined + “, “ + x);

This clears away the extraneous logic seen in “imperative” style coding, whereby the logic that frames the work to be done, ie, looping the array, is present. Doing the above in a loop-and-modify approach would take far more lines, and be much less obvious to read.

The developer has much less to stop and think about, and can stay concerned about the business logic they are trying to achieve.

In a broader sense, the way FP works is by allowing components to interact, or communicate, via discreet, portable chunks of code, that is, functions.

The principles that drive OOP (object oriented programming) are the same that drive FP: encapsulation and coding to interface.

Its just that the function is the smallest possible footprint of functionality to pass around. That makes it a cleaner design, because any time you reduce the surface area of components, or the footprint of the components themselves, the code is simpler.

Put another way, you could look at the passing of functions into other functions (in the array api or otherwise) as functional interfaces. The provider function (which consumes the parameter functions), are plugins to generalized logic.

This looks a lot like a strategy pattern in OOP, but again, the compactness of a function (and the dynamism of JavaScript’s type system) makes for a very tight component protocol.

FP vs. OOP

While on the subject of OOP, there are some winds blowing that claim one is better than the other. This is the topic for a full post, but I’ll mention here that, they are each good at different things.

You don’t choose between them in general; you choose between them for a given purpose.

Overall, OOP is good for building structure, and FP is good for performing actions. Objects and classes are like the car’s chassis, or the body’s bones, FP is like the electrical or nervous system.

You can see that this is true in the fact that modern UI frameworks like react, vue and angular all are component based systems, and these systems are analogous to, and often use, OOP to define structure.

Generators: Functions that Return Functions

Another commonly mentioned element of FP is functions that return functions. This is far less commonly encountered than functions-as-arguments.

This is because function generators are typically more useful on the framework, or library, side of things than the app client code side. The app developer is often responsible for providing functions to other functions to satisfy framework requirements, but rarely so to provide a function that creates a function.

Here’s an example from a common react pattern, where the fat-arrow syntax is chained:

handleChange = field => e => {

e.preventDefault();

// Handle event

}

The purpose of the above is to create an event handler that will accept the field in question, and then the event. This is useful because you can apply the same handleChange to multiple fields. In short: the same handler is useable on multiple fields.

Curried Functions

The above react handler is an example of a curried function. “Curried function” is a bit of a frustrating name: it honors a person, which is nice, but it doesn’t describe the concept, which is confusing.

In any case, the idea is that when you have functions that return functions, you can chain together calls to them, in a more flexible way than creating a single function with multiple arguments.

When calling these kinds of functions, you will encounter the distinctive “chained parenthesis” syntax:

handleChange(field)(event)

That is a speculative look at how React would call our handleChange() curried functions. We call the root function, passing in the field argument, then get another function back, and execute it, passing in the event object.

More Code Examples

Angular 4+ and RxJS

Angular 2 was a clean break and rewrite. One of the really visionary things it did was to adopt RxJS as it’s eventing system throughout. This netted two huge benefits: every event is handled everywhere with the same system; the event system is high-quality and rigorously maintained.

And as it turns out: RxJS is itself a beautiful example of FP.

The core idea in RxJS is to decouple code by creating event producers (observables) and event subscribers, then working on streams of events with functional operators.

This is similar to how the JS array method we saw earlier work; indeed, the idea of operating on a data collection as a set of individual instances is called a stream.

To drive home the similarity, many of the JS Array methods like map make their appearance as RxJS operators; the difference being, RxJS is architected to deal with streaming data from virtually any source, including live sources with indeterminate start, stop, intermittence and errors.

In the RxJS world, its called reactive programming. Here’s a simple example:

var button = document.querySelector(‘button’); Rx.Observable.fromEvent(button, ‘click’).subscribe(() => console.log(‘Clicked!’));

This should read fairly self-evidently. This is a simple event handler applied to a button element.

In Angular, you will see this everywhere. In handling component events and inter-component interaction, in transforming data, and in dealing with back-end API requests.

Here’s an example from Angular of listening for mouse events, then unsubscribing when the cursor moves into the top-left corner:



if (evt.clientX < 40 && evt.clientY < 40) {

subscription.unsubscribe();

}

}); const subscription = mouseMoves.subscribe((evt: MouseEvent) =>{console.log(`Coords: ${evt.clientX} X ${evt.clientY}`);if (evt.clientX < 40 && evt.clientY < 40) {subscription.unsubscribe();});

Here’s a more involved example:

const typeahead = fromEvent(searchBox, ‘input’).pipe(

map((e: KeyboardEvent) => e.target.value),

filter(text => text.length > 2),

debounceTime(10),

distinctUntilChanged(),

switchMap(() => ajax(‘/api/endpoint’))

);

I’m not going to deep dive into this here, but take a look at it: it is all FP. It essentially handles the eventing from a type-ahead feature, by using an observable (via pipe() command) to determine when to hit the backend for type ahead data.

(These examples are from the Angular docs).

Vue.js

Vue is cut from the same conceptual cloth as React and Angular. It to relies on FP, although not as heavily as the other two:

data: function() {

return {

item: {

name: 'Foo',

description: 'Bar',

}

}

}

The above is an example of a data field on a Vue component. It is a straight forward example of returning a function from another function.

Vuex is even more FP centered.

A Few More FP Terms

Lambda

Often confused as synonymous with anonymous function, which we covered here. In reality, more a synonym with first order function, also covered here.

A lambda is any use of functions as data, i.e., anonymous functions or functional references.

All anonymous functions are Lambdas. Not all Lambdas are anonymous functions. The best demystifier on this term I’ve found is here.

Pure Functions

A function without side effects.

These are hailed (validly, I think) as important because they are a dead-end for complexity.

What I mean by that is: a pure function takes its arguments, and returns its value, without modifying anything else. Repeatedly calling a pure function with the same arguments is guaranteed to return the same result.

In Angular’s Flux-style store (ngrx) the Reducers use pure functions as actions when modifying state. React encourages pure-functions, and insists that components act like pure functions when modifying props.

If you can represent logic as a pure function, do it. It means you have achieved your aim without unnecessarily modifying outside state or ramifying complexity.

Referential Transparency

This is closely related to pure functions.

In essence, this means a the function in question is transparent with respect to the references it modifies. Again: boils down to only params and return value are engaged in performing its work.

Conclusion

The bottom line is that JS has always been fairly FP oriented, as a result of its ingenious handling of functions. Event handlers off vanilla JS and the jQuery generation of frameworks were all FP style just as much as React.

The notion of events is central to FP. By using functions as the interaction point between software components, the interaction can be reduced to the idea of an event callback. This provides a very small point of contact, and the smaller the surface area between components, the better.

Again, the three dimensions of understanding for FP:

Nuts-And-Bolts: Understanding the code when you see it and use it in a similar fashion: critical for all JS developers

Understanding the code when you see it and use it in a similar fashion: critical for all JS developers Tactics: Understanding the tactics of FP enough to have it as a tool when coding; critical for architects or lead devs

Understanding the tactics of FP enough to have it as a tool when coding; critical for architects or lead devs Strategy: Understanding the strategy of FP enough to design systems that use it in conjunction with other approaches; more interesting, perhaps, if you are building something like React than using React

Hopefully, I’ve given you some wind in your sails here in going after all three.

Deep Thoughts on FP

A parting thought on the fourth dimension of FP (The Profound): I found myself reading about Abductive Reasoning, and thought: “This is some deep stuff.” FP was birthed out of the intense thinking that went into the formative moments of programmings evolution itself.

As such, it relates directly to the underlying logic and mental structures that underpin software itself.

I love that stuff. But it has little to do with coding in the everyday.