A function by any other name would work as well (part one)
Tags: javascript, functions, programming
Published: 2022-12-31 08:35:51

---
title: A function by any other name would work as well (part one)
published: true
description: Exploring the extensive world of the function as implemented in JavaScript
series: A little computer science for the inquisitive developer
tags: javascript, functions, programming
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tr2xui34c9r1al88vsu2.jpg
---

_Not quite the words of Shakespeare but better than my butchery of the words of Samuel Taylor Coleridge “Functions, functions everywhere, nor any call to async”. Ouch, sorry_

In this two-part article I will be exploring the extensive world of functions. Many of the concepts discussed can be found in other languages but we will focus specifically on functions as stipulated by JavaScript, or ECMAScript [ECMA-262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/) to be more exact. We will not be going deeply 'under the hood' but we will be exploring functions in as many forms as I can recall.

## Overview
Many programming languages possess a construct to provide the basic facility of functions but JS functions go beyond what many programming languages offer.

The primary use cases for functions are:
* Functions provide a way to break the solution (program) down into small pieces in a similar way to how we mentally break down the problem.
* Functions also provide a way of capturing reusable functionality and therefore reduces code duplication. Before [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) can about, functions were a key component for sharing code in a controlled manner and an enabler for code abstraction.

## Some history
Functions of course have their origins in mathematics but in imperative programming languages they were first seen in procedural languages such as (structured) BASIC, Pascal and C. In fact Pascal provides distinct keywords (procedure and function) for the purposes described above.

* Procedures can be regarded as “sub-programs” as they provide a container for logically grouped instructions but do not return a value.
* Functions on the other hand, provide a way to extend the programming language by creating new operations that return a value. They are intended to be more generic than procedures.

Before functions and procedures came about the nearest equivalent was the sub-routine as provided by the GOSUB command in structured BASIC. However, these used a line number instead of a meaningful name to reference the start of the code block. Subroutinrd also needed another keyword (RETURN) to provide an explicit exit and a way of restoring execution to the line after the line from where the sub-routine was called.

Programming languages prior to the "Procedural" group were largely without structure (such as assembly) and programs all too easily became convoluted and unmaintainable, and often acquired the term “spaghetti code” to describe the resultant mess.

To commence our investigation we will consider the anatomy of a “traditional” JS function and learn what makes JS different from other languages in regards to functions.

## Anatomy of a function
As we shall see, there are many ways to create a function but the one most common amongst programming languages uses a keyword like “function”, “func”, “def”, etc. In order for a program to reuse the function code, we usually have to give it a name, but in JS we can create ‘anonymous’ functions (as we shall see). 

```javascript
// A traditional function declaration
function functionName( parameterOne, parameterN) {
	// Zero or more statements
	// Zero or more return statements[1]
}

// Calling
functionName(argumentOne, argumentN);
```

After the optional function name we use parentheses to enclose a list of parameters, which are variables that can be supplied when the function is called. However, the values provided at the time of calling are usually called arguments. It is possible (especially in JS) to call the function with more or fewer arguments that parameters, which can lead to errors but JS is excessively forgiving in this regard. In JS as with many languages the alignment of arguments to parameters is by position but some languages employ a different strategy where the parameter names have to be provided with the value when the function is called.

The curly braces `{}` define the statement block for the function along with the scope of internal variables and functions, as will be described later.
 
[1] Coding standards often stipulate there should be no more than one return statement in a function but this can make the logic of some functions less readable than needs be. The ‘return’ statement signifies an exit point of a function similar to the Pascal return statement described above. However, in JS, unlike Pascal, a function does not have to formally return a value and if it does not; or the end of the function block is reached before ‘return’ is encountered, or 'return' is used without a value, the default return value from the function is ‘undefined’.

```javascript
function sayHi() {
  console.log('Hello, World!');
}

sayHi();
// Output: "Hello, World!"
// Return value: undefined
```

_Wait, back-up, if a function has no name how can it be used (called)?_

Unlike some languages, JS functions are ‘first-class’ objects and can be assigned as the value of a variable (using a function expression). They can be passed as arguments to another function, returned from a function and even created inside a function. Functions that expect a function as a parameter or returns a function have a special name "high-order" functions, which we will explore further later.

```javascript
const varFn = function(param) { return param * 6; };

varFn(7); // 42;
```

In the example above the function is created as an anonymous (it has no name) function expression (that returns a value) that is assigned to the variable varFn. In this form the function can be executed/called using ``varFn();`` call and can be reassigned as follows.

```javascript
const varFn2 = varFn;

varFn2(); // 42;
```

Another way to execute anonymous functions is known as IIFE (Immediately Invoked Function Expression). IIFEs are used as a form of single-use procedures and are a rather niche use case these days following the introduction of ES (ECMAScript) modules.

```javascript
(
function iife(parameter) {
	// statements
	// no return statement (most often)
}
)(argument);
```

The above function 'iife' is being declared and executed at (nearly) the same time. Lines 2-4 define the function and its statements. The parens (parentheses) around the declaration define the function as an expression (value). The following parens including arguments result in execution of the function expression immediately. Even if you do not think you need to give a function a name it is often helpful when debugging issues as it makes each function more obvious in the call stack.

## "Traditional" vs "Arrow" functions
So far I have used the term “traditional” to describe the function construct that has existed in JS from its inception and follows a pattern consistent with many other languages. Since [ECMAScipt](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/) 6 (2015) another form of function has been available known as the ‘arrow’ functions (or ‘fat arrow’ because of the syntax used `=>`). 

```JavaScript
const arrow = a => a > 0;

arrow(-1); // false: a < 0;
arrow(0); // false: a = 0;
arrow(1); // true: a > 0;
```

The origins of the Arrow function can be traced back to mathematics via the Functional Programming languages such as Lisp, where they also have the name “lambda functions/expressions”. The format/syntax will be quite familiar to those who use spreadsheets like MS Excel when calculating a formula. 

Although related, this should not be confused with AWS Lambda functions. They have been demonstrated to be so valuable to programming they can now be found in many popular languages.

```
;; Lisp
(lambda (a) (> a 0))

// C++
[](int a) { return a > 0; }

# Python
lambda a: a > 0

// C#
a => a > 0

// Java
a -> a > 0
```

## Scope and Closure
As stated above, within the braces of a function declaration we define the statements to be performed when the function is called. The statements have visibility of all the variables and functions defined outside the function (including those in the global scope) although position is important. Attempting to use some variables (those declared using `let` or `const`) can result in error as they cannot be used before they are declared (unlike `var`s). During execution variables declared within the 'scope' of the function are private and generally not visible outside the function. 

```javascript
const outerVariable = 6;

function mult() {
  const innerVariable = 7;

  console.log(outerVariable * innerVariable);
}

mult(); // 42 is shown in the console.

console.log(outerVariable * innerVariable);
// Error: innerVariable is not defined.
```

Once complete the scope of most functions (in JS there are exceptions) is destroyed and lost.

### Closures
For a formal definition of Closures please consult [MDN](https://en.wikipedia.org/wiki/Heinz_57?wprov=sfla1), but here is a less formal definition. In JS a closure is formed when the internal scope of a function is preserved beyond its execution by returning an internal reference, usually in form of another function. For example:

```javascript
function createClosure() {
  let closureState = 1;

  return function(stateChange) {
    closureState = stateChange(closureState);
    console.log(`New state: ${closureState}`);
  };
}

const closure = createClosure();

closure(s => s + 13);  // Console output `New state: 14`
closure(s => s * 3);  // Console output `New state: 42`
```

Notice how `createClosure` is called just once and holds the value `closureState`, which is not exposed directly. However, the function that is returned from the call, which is assigned to the constant `closure`, is called twice. Each call is made with a different argument (callback function) that is used to update the state (variable) inside the closure before it is logged to the console.

According to your point of view, it is either the execution of `createClosure` or its subsequent returning of the anonymous function that forms the closure.

## Not quite 57 varieties
[![Heinz 57 Varieties logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ha2as5lahsc6ilvziahj.png)](https://en.wikipedia.org/wiki/Heinz_57?wprov=sfla1)

JS supports a wide variety of functions types, the basic forms we have covered above. Before going really exotic let's investigate some others: 

### Methods
Methods are functions associated with and/or operate in the context of an object. The specific instance of an object can be referenced within a method using the `this` keyword, which is a little more dynamic in JS than other OOP languages and can be the source of some confusion.

```javascript
const instance = {
  message: 'Hello, World!',
  method() {
    console.log(this.message);
  }
};

instance.method();
// Output: 'Hello, World!'
```

As a simple "rule of thumb" for finding the value of `this`, locate when the function was called. For a method this will be of the form `object.method()`, so `this` is the object to the left of the dot.

When classes are used there is another form of method called a class/static method, as opposed to an object/instance method.

```javascript
class ExampleClass {
  static staticMethod() {
    return 'Hello, World!';
  }
}

console.log(ExampleClass.staticMethod()); // 'Hello, World!'
```

Static methods do not need to be called off an instantiated object but need to reference the class itself.

#### Getters and Setters (aka accessor methods)

There are also some special instance methods to control access to private (now we have the `#` syntax to support them) properties.

```javascript
class ExampleClass {
  #privateArray = ['a', 'b', 'c'];

  get latest() {
    return this.#privateArray.at(-1);
  }

  set latest(last) {
    this.#privateArray.push(last);
  }

  arrayContent() {
    return this.#privateArray.join();
  }
}

const exampleInstance = new ExampleClass();
console.log(exampleInstance.arrayContent()); // Output: "a,b,c"
console.log(exampleInstance.latest); // Output: "c"

exampleInstance.latest = 'd';
console.log(exampleInstance.arrayContent()); // Output: "a,b,c,d"
console.log(exampleInstance.latest); // Output: "d"
```

Finally on the topic of classes, there is another type of function called a `constructor`. If defined the constructor is always called when a new object is created (instantiated).

```javascript
class ExampleClass {
  constructor() {
    console.log('Hello, World!');
  }
}

const newInstance = new ExampleClass(); // 'Hello, World!'
```

## Wrapping up part one
In this first article we discovered the origins of functions in imperative programming languages. We decomposed the structure and investigated the roles of functions before exploring some of the varieties used/provided in JS.

In [part-two](https://dev.to/tracygjg/a-function-by-any-other-name-would-work-as-well-part-two-232) we will continue by discovering how JS supports asynchronous operations and enables a functional style of programming. We will also briefly investigate some of the newer, more exotic forms of function in JS.