Functional Programming in JavaScript — Higher Order JavaScript

Higher Order JavaScript

This chapter covers

  • Why JavaScript is a suitable functional language
  • JavaScript as a language that enables multi paradigm development
  • Immutability and policies for change
  • Understanding higher-order and first-class functions
  • Exploring the concepts of closures and scopes
  • Practical sue of closures

As applications get bigger, so does their complexity. No matter how good you think you are, turmoil is unavoidable if you don’t have the proper programming model in place.In chapter 1, I explained the reasons functional progrmaming is a compelling paradigm to adopt. But paradigms by themselves are just programming modes that need the right host language to come to life.

In this chapter, I take you on a fast-pass tour of a hybrid langue that mixes both object-oriented as well as functional programming: JavaScript. Of course, this is by no means an extensive study of the language; rather, I’ll focus on what allows JavaScript to be used functionally as well as where it falls short. One example of this is the lack of support for immutability. In addition, this chapter covers higher-order functions and closures, which totogethaer from the backbone that allows yo to write JavaScript in a function style. Without further ado, let’s dive in.

Why JavaScript?

I began by answering the question, ” Why functional?” Another question that comes to mind is, “Why JavaScript?” The answer to this question is simple: omnipresence. JavaScript is a dynamically typed, object-oriented, general-purpose language with an immensely expressive syntax. It’s one of the most ubiquitous languages ever created and can be seen in the development of mobile applications, se sites, web severs, desktop and embedded applications, and even databases. Given its extraordinary adoption as the language of the web, it begs to reasons the JavaScript is by far the most widely used FP language ever created.

Despite its C-like syntax, JavaScript draws lots of inspiration from functional languages like Lisp and Scheme. The commonalities lie in their support for higher-older functions, closures, array literals, and other features that make JavaScript a superb platform for applying FP techniques. In fact, functions re the main units of work in JavaScript, which means they’re used not only to drive the behavior off our applications, but also to define objects, create modules, and handle events.

JavaScript is actively evolving and improving. Backed by the ECMAScript (ES) standard, its next major release, ES6, adds many more features to the language: arrow functions, constants, iterators, promise, and other features that suit functional programming very well.

Despite the fact that it has lots of powerful functional features, it’s important to know that javaScript is as objet-oriented as it is functional. Unfortunately, the latter is rarely seen; most developers use mutable operations, imperative control structures, and instance state changes on objects, which are all virtually eliminated when adopting a functional style. Nevertheless, I feel it’s important to spend some time talking about JavaScript as an object-oriented language first so that you can better appreciate the key differences between the two paradigms. This will allow you to leap into functional programming more easily.

Functional vs. objet-oriented programming

Both functional and object-oriented programming (OOP) can be used to develop midsize-to-large systems. Hybrid languages like Scala and F#, for instance, lend both paradigms into a single language.JavaScript has a similar capability, and mastering it involves learning to use a combination of both; deciding where to draw the line depends on personal preference and the demands of the problems you’re tracking. Understanding where functional and object-oriented approaches intercept and differ can help you transition from one to the other, or think in terms of either one.

Object-oriented JavaScript

When I define a relationship between one object and another by saying it’s a subtype or derived type, I’m referring to the prototypal relationship that exists between the objects. It’s important to clarify that although JavaScript is object—oriented, it doesn’t have classical inheritance as you may have seen in other languages like Java.

In ES6, this mechanism for setting up prototype links between objects has been (erroneously, according to many) sugar-coated with keywords such as class and extends. This makes coding object inheritance more straightforward but hides the real work and power of JavaScript’s prototype mechanism.

Object-oriented applications, which are mostly imperative, rely heavily on object-based encapsulation to protect the integrity of their mutable state, both direct and inherited, in order to expose or manipulate that state and is fine-grained behavior, forming a cohesive package; this is the goal in object-oriented programs and why the central form of abstraction is the object.

Alternatively, functional programming removes the need to hide data from the callers and typically works with a smaller set of very simple data types. Because everything is immutable, e you’re free to work with objects directly, but this time through generalized functions that a live outside of an object’s scope. In the words data is loosely coupled to behavior. As you can see in figure 2.1, instead fine-grained instance methods, functional code relies on more coarse-grained operations that can crosscut or work across many data types. I this paradigm, functions become the main form of abstraction.

fig_2-1

Looking at figure 2.1, you see the two paradigms differ as you move up and to the right. In practice, some of the best object-oriented code I’ve sen uses both paradigms together — at their intersection. To do this, you need to treat objects as immutable entities or values and separate their functionality into functions that work on these objects. So a method on Person that looks like this

get fullname() {
  return [this._firstname, this._lastname].join(' ')
}

can be split out as follows:

var fullname = person => [person.firstname, person.lastname].join(' ')

As you know, JavaScript is a dynamical typed language (which means you never have to write explicit types next to object references), so fullname() will work with any type derived from Person (or nay object with properties firstname and lastname), as shown in figure 2.2. Given its dynamic nature, JavaScript functions support the use of generalized polymorphic functions. In other words, functions that use references to base types (such as Person) work on objects of derived types (such as Student or CollegeStudent).

var person = new Student('Alonzo', 'Church', '444-44-4444', 'Princeton')
p.fullname // -> Alonzo Church

fig_2-2

As you can see in figure 2.2, separating fullname() into a standalone function encourages you to avoid using the this reference to access object data. Using this is problematic because it gives you access to instance-level data outside of the method scope, which causes side effects. Using FP, object data is not intimately coulee to specific part of your code is far more reusable and maintainable.

Instead of creating lots of derived types, you can extend the behavior of function by passing other functions as arguments. To illustrate, let’s define the simple data model in the following listing, which contains the class Student that derives from Person. I use this model in most of the examples throughout this book.

//  Listing 2.1 Defining the `Person` and `Student` classes
class Person {
   constructor (firstname, lastname, ssn) {
     this._firstname = firstname
     this._lastname = lastname
     this._ssn = ssn
     this.address = null
     this._birthYear = null
   }
  
  get ssn() {
    return this._ssn
  }
  
  get firstname() {
    return this._firstname
  }
  
  get lastname() {
    return this._lastname
  }
  
  get address() {
    return this._address
  }
  
  get birthYear() {
    return thi._birthYear
  }
  
  set birthYear(year) {
    this._birthYear = year
  }
  
  set address(addr) {
    this._address = addr
  }
  
  toString() {
    return `Person(${this._firstname}, ${this._lastname})`
  }
}

class Student extends Person {
  constructor (firstname, lastname, ssn, school) {
    super(firstname, lastname, ssn)
    this._school = school
  }
  
  get school() {
    return this._school
  }
}

Given a person, your task is to find all of their friends that live in the same country as this person. Also, given a student, y our task is to find other students living in the same country and attending the same school .The object-oriented solution tightly couples operations, via this and super, to the objet and parent object, respectively:

// Person class
peopleInSameCountry(friends) {
  var retuls = []
  for (let idx in friends) {
    var friend = friends[idx]
    if (this.address.country === friend.address.country) {
      result.push(friend)
    }
  }
  return result
}

// Student class
studentInSameCountryAndSchool (friends) {
  var closeFriends = super.peopleInSameCountry(friends)
  var result = []
  for (let idx in closeFriends) {
    var firend = closeFriends[idx]
    if (friend.school === this.school) {
      result.push(friend)
    }
  }
  return result
}

On the other hand, because FP is based on purity and referential transparency, by isolating the behavior from the state you can add more operations by defining and combining new functions that work on those types. Doing this, you end up with simple objects in charge of storing data, and versatile functions that a work on those objects are arguments, which can be composed to achieve specialized functionality. You haven’t learned about composition yet, but it’s important to highlight another fundamental difference between the paradigms. In essence, what inheritance does for OOP, composition does for FP in terms of applying new behavior to different data types. To run this code, you”ll use the following dataset:

var curry = new Student('Haskell', 'Curry',
     '111-11-1111', 'Penn State')
curry.address = new Address('US')

var turing = new Student('Alan', 'Turing',
     '222-22-2222', 'Princeton')
turing.address = new Address('England');

var church = new Student('Alonzo', 'Church',
   '333-33-3333', 'Princeton')
church.address = new Address('US')

var kleene = new Student('Stephen', 'Kleene',
    '444-44-4444', 'Princeton')
kleene.address = new Address('US')

The object-oriented approach uses the method in Student to find all other students who attend the same school:

church.studenInSameCountryAndSchool([curry, turing, kleene])
// -> [kleene]

The functional solution, on the other hand, breaks the problem into smaller functions:

function selector(country, school) {
  return function(student) {
    return student.address.country() === country &&
      student.school() === school
  }
}
var findStudentsBy = function(friends, selector) {
  return friends.filter(selector);
}

findStudentsBy([curry, turing, church, kleene],
  selector('US', 'Princeton'))

//-> [church, kleene]

By applying functional programming, you create an entirely new function, findStudentsBy, that’s much easier to work with. Keep in main that this new function work with any objects tag relate to Person, as well as any school and country combination.

This clearly demonstrates the differences between the two paradigms. Object-oriented design focuses on the nature of data and data relationships, whereas functional programming focuses on the operations performed — behavior. Table 2.1 summarizes other key differences that are worth noticing:

tab_2-1

Despite their differences, building applications by blending these paradigms can be a powerful approach. On the one hand, you get a rich domain model with natural relationships among its constituent types; and on the other you have a set of pure functions that can work on these types. Where you draw the line will depend on how comfortable you feel using either paradigm. Because JavaScript is as object-oriented as it is functional, using it functionally will require some special attention in terms of controlling state changes.

Managing the state of JavaScript objects

The state of a program can be defined as a snapshot of the data stored in all of its objects at any moment in time. Sadly, JavaScript is one of the worst languages when it comes to securing an object’s state. A Javascript object is highly dynamic, and you can modify, add, or delete its properties at any point in time. In listing 2.1, if you expect _address to be encapsulated (the use of the underscore is purely syntactic) within Person, you’re wrong. You have complete access to the property outside of the class to do whatever you place or even to delete it.

With freedom comes great responsibility. Although this may give you the liberty to do many slick things like dynamic property creation, it can also lead to code that’s extremely difficult to maintain in midsize-to-large programs.

Treating objects as values

Strings and numbers are probably the easiest dat types to work with in any programming language. Why do you think that is? Part of the reason is that, traditional, these primitive types are inherently immutable, which gives us a certain peace of main that other user-defined types don’t. In functional programming, we call types that behave this way values. In chapter 1, You learned to think about immutability and this requires effectively treating any object as a value; doing so allows you to work with functions that pass objects around and not worry about them being altered.

Despite all the syntactic sugar added around classes in ES6, JavaScript objects are nothing more than bags of attributes that can added, removed, and changed at any time. What can you do to remedy this? Many programming languages support constructs that make an object’s properties immutable. One example is Java’s final keyword. Also, languages like F# have immutable, uses stated otherwise. At present, you don’t have this luxury in Javascript. Although JavaScript primitive types can’t be changed, the state of the variable that refers to a primitive can. Therefore, you need to be able to provide, or at least emulate, immutable references to data so that your user-defined objects behave as if they were immutable.

ES6 uses the const keyword to create constant references. This moves the needle in the right direction because constants can’t be reassigned or re-declared. In practical functional programming, you can use constant a means to bring simple configuration data (URL strings, database names, and so on) into your function program if need be. Although reading from an external variable is a side effect, the platform provides special semantics to constants so they won’t change unexpectedly between function calls. Here ‘s an example of declaring a constant value:

const gravity_ms = 9.806
gravity_ms = 20 // <= JavaScript runtime won't allow this reassignment  

But this doesn’t solve the problems of mutability t the level that FP retries. You can prevent a variable from being reassigned, but how can you prevent an object’s internal state from changing? The code would be perfectly acceptable:

const student = new Student('Alonzo', 'Church', '666-66-6666', 'Princeton')

student.lastname = 'Morning' // Property has been changed.

What you need is a sticker policy for immutability; an encapsulation is a good strategy to protect against mutations. For simple object structures, a good alternative is to adopt the Value Object pattern. A value object is one whose quality doesn’t depend on identity or reference, just on its value; once declared, its state may not change. In addition to numbers and strings, simple examples of value objects are types like tuple , pair , point , zipCode , coordinate , money , date , and others. Here’s an implementation for zipCode :

function zipCode(code, location) {
  let _code = code
  let _location = location || ''
  
  return {
    code: function () {
      return _code
    },
    location: function () {
      return _location
    },
    fromString: function (str) {
      let parts = str.split('-')
      return zipCode(parts[0], parts[1])
    }
    toString: function() {
      return _code + '-' + _location
    }
  }
}

const princetonZip = zipCode('08544', '3345')
princetonZip.toString() // -> '08544-3345

In JavaScript, you can use functions and guard access to a ZIP code’s internal state by returning an object literal interface that exposes a small set of methods to the caller and treats _code and _location as pseudo-private variables. These variables are only accessible in the object literal via closures, which you’ll see later in this chapter.

The returned object effectively behaves like a primitive that has no mutating methods. Hence the toString method, although not a pure function, behaves like one and is pure string representation of this object. Value objects are lightweight and easy to work with in both functional and OOP. In conjunction with const, you can create objects with semantics similar to those of a string or number. Let’s consider another example:

function coordinate(lat, long) {
  let _lat = lat
  let _long = long
  
  return {
    latitude: function () {
      return _lat
    },
    longitude: function () {
      return _long
    },
    translate: function (dx, dy) {
      return coordinate(_lat + dx, _long + dy)  // Returns a new copy with the translated coordinates
    },
    toString: function () {
      return '(' + _lat + ',' + _long + dy)
    }
  }
}

const greenwich = coordinate(51.4778, 0.0015)
greenwich.toString() // => `(51.4778, 0.0015)`

Using methods to return new copies (as in translate) is another way to implement immutability. Applying a translation operation on this object yields a new coordinate object:

greenwich.translate(10, 10).toString()  // => '(61.4778, 10.0015)'

Value Object is an object-oriented design pattern that was inspired by functional programming. This is another example of how the paradigms elegantly complement each other. This pattern is ideal, but it’s not enough for modeling entire real-world problem domains. In practice, it’s likely your code will need to handle hierarchical data (as you was with Person and Student earlier) as we ll as interact with legacy objects. Luckily, JavaScript has a mechanism to emulate this using with Object.freeze.

Deep-freezing moving parts

JavaScript’s new class syntax doesn’t define keywords to mark fields as immutable, but it does support an internal mechanism for doing so by controlling some hidden object meta properties like writeable. By setting this property to false, JavaScript’s Object.freeze() function can prevent an object’s state from changing. Let’s begin by freezing the person object from listing 2.1:

var person = Object.freeze(new Person('Hasskell', 'Curry', '444-44-4444'))
person.firstname = 'Bob'    // <= not allowed

Executing the preceding code makes the attributes of person effectively read-only. Any attempt to change them (_firstname, in this case) will result in an error:

TypeError: Cannot assign to read only property '_firstname' of #<Person>TypeError: Cannot assign to read only property '_firstname' of #<Person>

Object.freeze() can also immobilize inherited attributes. So freezing an instance of Student works exactly the same way and follows the object’s prototype chain protecting every inherited Person attribute. But it can’t be used to freeze nested object attributes, as shown in figure 2.3.

fig_2-3

Here’s the definition for the Address type:

class Address {
  constructor(country, state, city, zip, street) {
    this._country = country
    this._state = state
    this._city = city
    this._zip = zip
    this._street = street
  }
  
  get street() {
    return this._street
  }
  
  get city() {
    return this._city
  }
  
  get state() {
    return this._state
  }
  
  get zip() {
    return this._zip
  }
  
  get country() {
    return this._country
  }
}

Unfortunately, no errors will occur in the following code:

var person = new Person()
person.address = new Address()

person = Object.freeze()

person.address._country = 'France'  // -> allowed!
person.address.country  // -> 'France'

Object.freeze() is a shallow operation. To get around this, you need to manually freeze an object’s nested structure, as shown in the following listing.

// Listing 2.2 Recursive function to deep-freeze an object

var isObject = (val) => val && typeof val === 'object'

function deepFreeze(obj) {
  if (isObject(obj)) && !Object.isFrozen(obj)) {
    Object.keys(obj).forEach(name => deepFreeze(obj[name])) // Calls itself recursively
    
    Object.freeze(obj)  // Freezes the root object
  }
  return obj
}

I’ve just shown some techniques you can use to enforce a level of immutability in your code, but it’s unrealistic to expect that you can create entire applications without ever modifying any state. Thus, struck policies when creating new objects from originals (as with coordinate.translate()) are extremely beneficial in your quest to reduce the complexities and intricacies of JavaScript applications. Next, I discuss the best alternative to centrally managing object changes immutably using a functional approach called lenses.

Navigating and modifying object graphs with lenses

In OOP, you’re accustomed to calling methods that change the internal contents of a stageful object. This has the disadvantage of never being able to guarantee the outcome of retrieving the state and may break the functionality of part of the system that expects the object to stay intact. You could opt to implement your own copy-on-write strategy and return new objects from each method call – a tedious and error-prone process, to say the least. A simple setter function integrates the Person class would look like this:

set lastname(lastname) {
  return new person(this._firstname, lastname, this._ssn) // You don't have to manually copy the state of all other properties into a new instance.
}

Now imagine having to do this for every single property of every type in your domain model. You need a solution for mutating stageful objects, in an immutable manner, that’s unobtrusive and doesn’t require hardcoding boilerplate code everywhere. Lenses, also known as functional references, are functional programming’s solution to accessing and immutably manipulating attributes of stateful data types. Internally, lenses work similarly to a copy-on-write strategy by using an internal storage component that knows how to properly manage and copy state. You don’t need to implement this yourself; rather, you can use a functional JavaScript library called Ramda.js. By default, Ramdaexposes all of its functionality via the global object R. Using R.lenProp, you can create a Lens that wraps over the lastname property of Person:

var person = new Person('Alonzo', 'Church', '444-44-4444')
var lastnameLens = R.lensProp('lastname')

You can use R.view() to read the contents of this property:

R.view(lastnameLens, person)    // => 'Church'

This is, for all practical purposes, similar to a get lastname() method. Nothing impressive so far. What about the setter? Here’s where the magic comes in. Now, calling R.set creates and returns a brand-new copy of the object containing the new value and preserves the original instance state (copy-on-write semantics for free!):

var newPerson = R.set(lastnameLens, 'Mourning', person)
newPerson.lastname  // => 'Mourning'
person.lastname // => 'Church'

Lenses are valuable because they give you an unobtrusive mechanism for manipulating objects, even if these are legacy objects or objects outside of your control. Lenses also support nested properties, like the address property of Person:

person.address = new Address(
   'US', 'NJ', 'Princeton', zipCode('08544','1234'),
   'Alexander St.')

Let’s create a lens that navigates to the address.zip property:

var zipPath = ['address', 'zip']
var zipLens = R.lens(R.path(zipPath), R.assocPath(zipPath)) // (?)
R.view(zipLens, person)  //=> zipCode('08544', '1234')

Because lenses implement immutable setters, you can change the nested object and still return a new Person object:

var newPerson = R.set(zipLens, person, zipCode('90210', '5678'))
R.view(zipLens, newPerson) //-> zipCode('90210', '5678')
R.view(zipLens, person)    //-> zipCode('08544', '1234')
newPerson !== person //-> true

This is great because now you have getter and setter semantics in a functional way. In addition to providing a protective immutable wrapper, lenses also fit extremely well with FP’s philosophy of isolating field-acnes logic away from the project, eliminating the reliance on this ,and giving you powerful functions that know how to reach into and manipulate the contents of any object.

Functions

In functional programming, functions are the basic units of work, which means everything centers around them. A function is any callable expression that can be evaluated by applying the () operator to it. Functions can return either a computed value or undefined (void function) back to the caller. Because FP works a lot like math, functions are meaningful only when they produce a useable result (not null or undefined); otherwise, the assumption is that they modify external data and cause side effects to occur. We can distinguish between expressions (functions that produce a value) and statements (functions that don’t). Imperative and procedural programming are mostly made up of ordered sequences of statements; but FP is entirely expressional, so void functions don’t serve a purpose in this praradigm.

JavaScript functions have two important characteristics that are the bread and butter of its functional style: they’re first-class and higher-order. We’ll explore both of these ideas in detail next.

Functions as first-class citizens

In JavaScript, the term first-class comes from making functions actual objects in the language – also called first-class citizens. You’re probably used to seeing functions declared like this:

function multiplier(a,b) {
  return a * b
}

But JavaScript offers more options. Like objects, a, a function can be

  • Assigned to variables as an anonymous function or lambda expression:
    // Anonymous function
    var square = function (x) {
    return x * x
    }
    
    // Lambda expression
    var square = x => x * x
    
  • Assigned to object properties as methods:
    var obj = {
    method: function (x) { return x * x}
    }
    

    Where a function call uses the () operator, as in square(2), the function object is printed as follows:

    square
    // function (x) {
    //    return x * x
    }
    
  • Although not common practice, functions can also instantiated via constructors, which is proof of their first-class nature in JavaScript. The constructor takes the set of formal pramters, the function body, and the new keyword, like so:
    var multiplier = new Function('a', 'b', 'return a * b')
    
    multiplier(2, 3) // => 6
    

In JavaScript, every function is an instance of the Function type. A function’s length property can be used to retrieve the number of formal parameters, and methods such as apply() and call() can be used to call function with contexts (more about them in the next section).

The right side of an anonymous function expression is a function object with an empty name property. Yo can use anonymous function to extend or specialize a function’s behavior by passing them as arguments. Consider JavaScript’s native Array.sort(comparator) as an example; it takes a comparator function object. By default, sort converts values being stored into strings and uses their Unicode values as natural string criteria. This is limiting and often not what you intend. Let’s look at a couple of examples:

var fruit = ['Cocount', 'apples']
fruit.sort() // => ['Cocount, 'apples]

var ages = [1, 10, 21, 2]
ages.sort()

As a result, sort() is a function whose behavior is frequently driven by the criteria implemented in the comparator function, which by itself is almost useless. You can force proper numerical comparisons and sort a list of people by age using custom function argument:

people.sort(p1, p2) => p1.getAge() < p2.getAge())

The comparator function takes two parameters, p1 and p2, with the following contract:

  • If comparator return less than 0, comes before p2
  • If comparator returns 0, leave p1 and p2 unchanged.
  • If comparator returns greater than0, p1 comes after p2.

In addition to being assignable, JavaScript functions like sort() accept other functions as arguments and belong to a category called higher-order functions.

Higher-order functions

Because functions behave like regular objects, you can intuitively expect that they can be passed in as function arguments and returned from other functions. These are called higher-order functions.You saw the comparator function for Array.sort(); let’s quickly look at some other examples:

The following snippet shows that functions can be passed to other functions. The applyOperation function takes two arguments and applies any operator function to both of them:

function applyOperation(a, b, opt) {
  return opt(a, b)
}

var multipler = (a, b) => a * b

applyOperation(2, 3, multiplier)    // => 6

In the next example, the add function takes an argument and returns a function that, in turn, receives a second argument and adds them together:

function add(a) {
  return function(b) {
    return a + b
  }
}
add(3)(3) // => 6

Because functions are first-class and higher-order, JavaScript functions can behave as values, which implies that a function is nothing more than a yet-to-be-executed value defined immutably based on the input provided to the function. This principle is embedded in everything that yo duo in functional programming, especially when you get into function chains. When building function chains, you’ll always rely on function names to point to a piece of a program that will be executed as part of an entire expression.

You can combine higher-order functions to create meaningful expressions from smaller pieces and simplify many programs that would otherwise be tedious to write. As an example, say you need to print a list of people who live n the United States. You first approach would probably look like this imperative code:

function printPeopleInTheUs(people) {
   for (let i = 0; i < people.length; i++) {
     var thisPerson = people[i];
     if(thisPerson.address.country === 'US') {
       console.log(thisPerson);
    }
} }
printPeopleInTheUs([p1, p2, p3])

Now, suppose you need to support people living in other countries, as well. With higher-order functions, you can nicely abstract out the action performed on each person: in this case, printing to the console. You can freely supply any action function you want to a higher-order printPeople function:

function printPeople(people, action) {
  for (let i = 0; i < people.length; i++) {
    action (people[i])
  }
}

var action = function(person) {
  if (person.address.country === 'US') {
    console.log(person)
  }
}

printPeople(people, action)

A notice pattern that occurs in languages like JavaScript is the function names can be passive nouns like multiplier, comparator, and action. Because they’re first=class, functions can be a assigned to a variables and executed at a later time. Let’s refactor printPeople to take full advantage of higher-order functions:

function printPeople(people, selector, printer) {
  people.forEach(function (person) {
    if(selector(person)) {
      printer(person)
    }
  })
}

This is the mindset you must develop to fully embrace functional programming. This exercise shows that the code is a lot more flexible than what you started with, because you can quickly swap (or configure) the criteria for selection as well as change where you want to print. Chapters 3 and 4 focus on this topic and the use of special libraries to fluently chain operations together and build complex programs for simple parts.

Looking ahead (?)

I want to briefly pause my discussion of core JavaScript to elaborate further on the program in this section in this section and combine some concepts I’ve briefly touched on. This is a bit advanced for now, but soon you’ll learn how to build programs this way using FP techniques. You can create supporting functions using lenses that you can use to access an object’s properties:

var countryPath = ['address', 'country']
var countryL = R.lens(R.path(countryPath), R.assocPath(countryPath))
var inCountry = R.curry((country, person) => R.equals(R.view(countryL, person), country))

This is much more functional than before:

people.filter(inCountry('US')).map(console.log)

As you can see, the country name becomes another parameter that can be changed to anything you want. This is something to look forward in the following chapters.

In JavaScript, functions not only are involved, they’re also applied. Let’s talk about this unique quality of JavaScript’s function-invocation mechanism.

Types of function invocation

JavaScript’s function-invocation mechanism is an interesting part of the language and different from other programming languages. JavaScript gives you complete freedom to dictate the runtime context in which a function is invoked: the value of this in the function body. JavaScript functions cane invoked in many different ways:

  • _As a global function_ — The reference to this is set either to the global object or to undefined (in strict mode):
    function doWork() {
    this.myVar = 'Some value'
    }
    doWork() // Calling doWork() glboally causes the "this" reference ot point to the global object.
    
  • _As a method_ — The reference to this is set to the owner of the method. This is an important part of JavaScript’s object-oriented nature:

    javascript

    var obj = {

    prop: 'Some property',

    getProp: function () { return this.prop }

    }

    obj.getProp() // Invoking an objec's method points "this" to the owning object.

  • _As a constructor by prepending the call with new_ — This implicitly returns the reference to the newly created object:
    function MyType(arg) {
    this.prop = arg
    }
    var someVal = new MyType('some argument') // Calling a fucntion with new sets the "this" reference to point to the object that's being constructed and implicitly returned.
    

As you can see from these examples, unlike in other programming languages, the this reference is set based on how the function is used. (Globally, as an object method, as a constructor, and so on) and not by its lexical context (its location in the code). This can lead to the code that’s hard to understand, because you need to pay close attention to the context in which a function is executing.

I included this section because it’s important for you to know as a JavaScript developer, but as I’ve indicated several times, the use of this in functional code is rarely seen (in fact, it’s avoided at all costs). It’s heavily used by library and tool implementers for special cases that demand benign the language context to perform incredible feats. These often involve the function methods apply and call.

Function methods

JavaScript supports calling functions via the function method (like meta-functions) call and apply, which belong to the function’s prototype. Both methods are used extensively when scaffolding code is built so that API users can create new functions for existing ones. Let’s take a quick look at writing a negate function, for example:

function negate(func) {
  return function() {
    return !func.apply(null, arguments)
  }
}

function isNull(val) {
  return val === null
}

var isNotNull = negate(isNull)

isNotNull(null) // => false
isNotNull({})   // => true

The negate function creates a new function that invokes its argument and then logically negates it. This example uses apply, but you could use call the same way; the difference is that the latter accepts an argument list, whereas the former takes an array of arguments. The first argument, thisArg, can be used to manipulate the function context as needed. Here are both signatures:

Function.prototype.apple(thisArg, [argsArray])
Function.prototype.call(thisArg, arg1, arg2, ...)

If thisArg refers to an object, it’s set to the object the method is called on. If thisArg is null, the function context is set to the global objects, and the function behaves like a simple global function. But if the method is a function is strict mode, the actual value of null is passed in/

Manipulating the function context through thisArg opens the door to many different techniques. This is discouraged in functional programming, because ti never relies on the context state (recall that all data is provided to functions as arguments), so I won’t spend any more time on this feature.

Closures and Scopes

Prior to JavaScript, closures only existed in FP languages used in certain specific applications. JavaScript si the first to adopt it into mainstream development and significantly change the way in which we write code. Let’s revisit the zipCode type:

function zipCode(code, location) {
  let _code = code
  let _location = location || ''
  
  return {
    code: function () {
      return _code
    },
    location: function () {
      return _location
    },
    ...
  }
}

If you examine this code closely, you’ll realize that the zipCode function returns an object literal that seems to have full access to variables declared outside of its scope. In other words, after zipCode has finished executing, the resulting object can still see information declared in this enclosing function:

const princetonZip = zipCode('08544', '3345')
princetonZip.code() // => '08544'

This a bit mind-bending, and it’s all thanks to the closure that forms around object and function declarations in JavaScript. Being able to access data this way has many practical uses; in this section, we’ll look at using closures to emulate private variables fetch data from the server, and force block-scoped variables.

A closure is a data structure that binds a function to its environment at the moment it’s declared. It’s based on the textual location of the function declaration; therefore, a closure is also called a static or lexical scope surrounding the function definition. Because it gives functions access to its surrounding state, it makes code clear and readable. As you’ll see shortly, closures are instrumental not only in functional programs when you’re working with higher-order functions, but also for event-handling and callbacks, emulating private variables and mitigating some of JavaScript’s pitfalls.

The rules that govern the behavior of a function’s closure are closely related to JavaScript’s scoping rules. A scope groups a set of variable bindings and defines a section of code in which variable is defined. In essence, a closure is a function’s inheritance of scopes akin to how an object’s method has access to tis inherited instance variables — both have references to their parents. Closures are readily seen in the case of nested functions. Here’s quick example:

function makeAddFucntion(amount) {
  function add(number) {
    return number + amount
  }
  return add
}

function makeExponentialFunction(base) {
  function raiseThreeTo(exponent) {
    return Math.pow(base, exponent)
  }
  return raise
}

var addTenTo = makeAddFunction(10)
addTenTo(10)

var raiseThereTo = makeExponentialFunction(3)
raiseThreeTo(2) // => 9 

It’s important to notice in this example that even though the amount and base variables in both functions are no longer in the active scope, there’re still accessible from the returned function when invoked. Essentially, you can imagine the nested functions add and raise as functions that package not only their computation but also a snapshot of all variables surrounding them. More generally, as shown in figure 2.4, a function’s closure includes the following:

  • All function parameters (params and params2, in this case)
  • All variables in the outer scope (including all global variables, of course), as well as those declared after the function additionalVars

fig_2-4

Let’s see this in action in the next listing.

// Listing 2.3 Closures at work
var outerVar = 'Outer'
function makeInner(params) {
  var innerVar = 'Inner'
  
  function inner() {
    console.log(`I can see: ${outerVar}, ${innerVar}, and ${params}`)
  }
    return inner
}
var inner = makeInner('Params')
inner()

Running this code prints out the following:

'I can see: Outer, Inner, and Params'

At first glance, this may seem unintuitive and somewhat mystical. You’d expect that local variables — InnerVar in this case — would cease to exit or be garbage-collected after makeInner returned, thereby printing undefined. Behind the scenes, it’s again the magic of closures that make this possible.Behind the scenes, it’s again the magic of closures that makes this possible. The function returned from makeInner remembers all the variables in the scope at the time it was declared and also prevents them from being disposed of. The global scope is also part of this closure, giving access to outerVar as well;

You may wonder how variables (like additionalVars) declared after a function is declared can also be included as part of its closure. To answer this, you need to understand that JavaScript has three forms of scoping: global scope, function scope, and a pseudo-block scope.

Problems with the global scope

Global scope is the simplest from the scoping, but also the worst. Any objects and variables declared in the outermost level of a script (not contained in any function) are part of the global scope and accessible from all JavaScript code. Recall that our goal in functional programming to prevent any observable changes to ripple out from functional programming is to prevent any observable changes to ripple out from functions; but in the global scope, every line that executes causes visible changes to occur.

It’s tempting to use global variables, but they’re shared among all scripts loaded onto the page, which can easily lead to namespace collisions if your JavaScript code isn’t packaged into modules. Polluting the global namespace can be problematic because you run the chance of overriding variables and functions declared in different files.

Global data has the detrimental effect of making programs hard to reason about because you’re obligated to keep a mental note of the state of all variables at any point in time. This is one of the main reasons program complexity increases as you code becomes larger. It’s also conductive to having side effects in your functions, because you inevitably create external dependencies when reading from or writing to it. It should be obvious at this point that when writing in an FP style, you’ll avoid using global variables at all cost.

JavaScript’s function scope

This is JavaScript’s preferred scoping mechanism. Any variables declared in a function are local to that function and not visible anywhere else. Also, when a function returns, any local variables declared in are deleted with it. So in the function

function doWork() {
  let student = new Student(...)
  let address = new Address(...)
  // do more work
}

The variables student and address are bound in doWork() and are inaccessible by the outside world. As you can see in figure 2.5, resolving a variable by name is similar to the prototype name-resolution chain described earlier. It begins by checking the innermost scope and works its way outward. JavaScript’s scoping mechanism works as follows:

  • It checks the variable’s function scope.
  • If not in the local scope, it moves outward into the surrounding lexical scope, searching for the variable reference until it reaches the global scope.
  • If the variable can’t be reference, JavaScript returns undefined.

Consider this code sample:

var x = 'Some value'
function parentFunction() {
  function innerFunction() {
    console.log(x)
  }
  return innerFunction
}
var inner = parentFunction()
inner()

fig_2-5

If you have experience with any other programming language, you’re probably used to function scope. But given JavaScript’s C-like syntax, you may expect block scopes to work in similar ways.

A pseudo-block scope

Unfortunately, standard ES5 JavaScript doesn’t support block-level scope, which is formed in brackets, {}, under control structure such as for, while,if, and switch statements. The exception is the error variable passed into a catch block. The with statement can do some level of block scope, but its use is discouraged and is removed in strict mode. In other C-like languages, a variable declared in an If statement (myVar, in the case) such as the following

if (someCondition) {
  var myVar = 10
}

Isn’t accessible from outside the code block. This can be confusing for developers who are accustomed to that style and are new to JavaScript. Because JavaScript has function scope exclusively, any variables declared in a block are accessible at any point in the function. This can also be a nightmare for JavaScript developers, but there are ways to overcome it. Let’s look at the problem at hand:

function doWork() {
  console.log(myVar)    // => undefined
  if (!myVar) {
    var myVar = 10
  }
  console.log(myVar)    // => 10
}
doWork()

The variable myVar is declared in the if statement, but it’s visible from outside the block. Strangely enough, running this code prints out the value 10. This can be baffling, especially for developers used to the more common block-level scope. An internal JavaScript mechanism hosts variable and function declarations to the top of the current scope — the function scope, in this case. This can make writing loops unsafe; pay attention to the following listing:

// Listing 2.4 Ambiguous loop-counter problem
var arr = [1, 2, 3, 4]
function processArr() {
  console.log("place 0: " + i) // => undefined
  function multipleBy10(val) {
    // console.log("place 2: " + i) // => 0
    i = 10
    // console.log("place 3: " + i) // => 10
    return val * i
  }
  for(var i = 0; i < arr.length; i++) {
    // console.log("place 1: " + i) // => 0
    arr[i] = multipleBy10(arr[i])
    // console.log("place 4: " + i) // => 10
  }
  return arr
}
processArr()    // => [10, 2, 3, 4]

The loop counter I is moved to the top of the function and becomes part of the multipleBy10 function’s closure. Forgetting to use the keyword var in i‘s declaration fails to create locally scoped variable in multiplyBy and accidentally modifies the loop counter to 10.

Good IDEs and linters can help mitigate these issues, but even they aren’t much help in the face of hundreds of lines of code. In the later section, we’ll look at better solutions that are both more elegant and less error-prone than standard loops: techniques that take full advantage of higher-order functions and help mitigate these pitfalls. As you’ve seen throughout this article, ES6 JavaScript provides the let keyword to help resolve this loop-counter ambiguity by properly binding the loop counter to its enclosing block:

for(let i = 0; i < arr.length, i++) { // let resolves the hoisting problem and scopes i in the right place. Outside the loop, i isn't defined.
  // ...
}
i   // i === undefined

This is a step in the right direction, and the reason why I prefer using let than var in scope-bounded variables, but manual loops have other shortcoming that we’ll remedy in the later articles. Now that you understand what makes up a function’s closure and tis interplay with scope mechanics, let’s turn to some practical uses of closures.

Practical applications of closures

Closures have many practical applications that are important to apply when implementing large JavaScript programs. There aren’t specific to functional programming, but they do take advantage of JavaScript’s function mechanism:

  • Emulating private variables
  • Making asynchronous server-side calls
  • Creating artificial block-scoped variables

Emulating private variables

Unlike JavaScript, many languages provide a built-in mechanism to define internal properties of an object by setting accessibility modifiers (like private). JavaScript doesn’t have a native keyword for provided variables and functions to be accessed only in the scope of an object. Encapsulation can play in favor of immutability because you can’t change what you can’t access.

Using closures, however, it’s possible to emulate this behavior. One example is returning an object, much like zipCode and coordinate in the earlier example. These functions return object literals with methods that have access to any of the outer function’s local variables, but don’t expose these variables, therefore effectively making them private.

Closure can also provide a way to manage your global namespace to avoid globally shared data. Library and module authors take closures to the next level by hiding an entire module’s private methods and data. This is referred as the Module pattern because it uses a single _immediately invoked function expression_ (IIFE) to encapsulate internal variables while allowing you to export the necessary set of functionality to the outside world and severely reduce the number of global references.

Note As a general best practice, I recommend packaging all of your functional code inside well-encapsulated modules. You can transfer all the core principles of functional programming you’ve learned in this book to the level of modules.

Here’s a short sample of a module skeleton:

var MyModule = (function MyModule(innerMyModule) {
  let _myPrivateVar = 1
  
  innerMyModule.method1 = function () {
    console.log(_myPrivateVar + ": method 1")
    // do work
  }
  innerMyModule.method2 = function () {
    console.log(_myPrivateVar + ": method 2")
    // do work
  }
  return innerMyModule
}(MyModule || {}))

MyModule.method1()

The object MyModule is created global and passed into a function expression, created with the function keyword, and immediately executed when the script is loaded. Due to JavaScript’s function scope,_myPrivateVar and nay other private variables are local to the wrapping function. The closure surrounding the two exported method is what allows the object to safely access all of the module’s internal properties. This is compelling because it keeps your global footprint while exposing an object with lots of encapsulated sate and behavior. This module pattern has been adopted in all the functional libraries we’ll use throughout this book.

Making asynchronous server-side calls

JavaScript’s first-class, higher-order functions can be passed into other functions as callbacks. Callbacks are useful as hooks to handle events in an unobtrusive manner. Suppose you need to make a request to the server and want to be noticed once the data has been received. The traditional idiom is to provide a callback function that will handle the response:

getJSON('/students', (students) => {
    getJSON('/students/grades',
        grades => processGrade(grades),
        error => console.log(error.message))
    },
   (error) => console.log(error.message)
)

getJSON is a higher-order function that takes two callbacks as arguments: a success function and an error function. A common pattern that occurs with asynchronous code as well as event handling is that you can easily corner yourself into deeply nested function calls; this forms the unpleasant “callback pyramid of doom” when you need to make several subsequent remote calls to the server. As you’ve probably experienced, when the code is deeply nested, it becomes hard to follow. In chapter 8, you’ll learn best practices for how to basically flatten this code into more fluent and declarative expressions that chain together instead of nesting.

Emulating blocked-scope variables

Using closures can provide an alternative solution to the ambiguous loop-counter variable example in listing 2.4. As I mentioned earlier, the underlying issue is JavaScript’s lack of block-scope semantics, so the objective is to artificially create this block scope. What can you do about this? Using let mitigates many of the issues with the traditional looping mechanism, but a functional approach would be to take advantage of closures and JavaScript’s function scope and consider using forEach. Now, instead of worrying about trying the loop counter and other variables in scope, you can effectively wrap the loop body inside the loop as if emulating a function-scope block under the loop statement. As you’ll learn later, this helps you call asynchronous behavior while iterating over collections:

arr.forEach(function(elem, i) {
  ...
})

This chapter covered just the basics of JavaScript, to help you understand some of its limitations when it’s used functionally and prepare you for the functional techniques covered in later chapters. If you seek a much deeper understanding of the language, there are entire books dedicated to this subject that teach the concepts of objects, inheritance, and closures much more thoroughly.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s