Cubes to Smoke — MattysFlicks — (CC BY 2.0)

Note: This is part 1 of the “Composite Software” series on JavaScript ES6+ learning functional programming and composite software techniques. The next part is more exciting, stay tuned!

When I was about six years old, I spent most of my time playing computer games with my best friend. He had a room full of computers in his house, and they were like magic to me. I spent a lot of time exploring all the games. One day, I asked my friend, “How can we make a game?”

He didn’t know, so we asked his father, who pulled down a book on writing games in Basic from a high shelf. That was the beginning of my programming journey. By the time algebra was taught in public school, I knew it, because programming was basically algebra, and algebra was everywhere in programs.

 

The rise of composite software

In the early days of computing, before computers could perform most calculations, there were two great computer scientists, Alonzo Church and Alan Turing. They developed two different, but equivalent, models for general computation. Both models can compute anything that can be computed (hence the name “general purpose”).

Alonzo Church invented the lambda calculus. λ calculus is a general calculation model based on function combination. Alan Turing is famous for his Turing machine. Turing machine is a general computing model that defines a theoretical device that can process symbols on strips.

Together they proved that the λ calculus and Turing machines are functionally equivalent.

The calculus of λ is about combinations of functions. Function composition is a very expressive way of composing software. This article will discuss the importance of function composition in software design.

 

There are three things that make the lambda calculus different,

  1. Anonymous functions are allowed: add(x, y) => x + y can be expressed as (x, y) => x + y.
  2. The function in the lambda calculus takes only a single input and is unary. If multiple arguments are required, the function takes one input, returns a new function that takes the next argument, and so on. The n-element function (x, y) => x + y can be expressed as the unary function x => y => x + y. Such a transformation from an n-yuan function to a 1-yuan function is called a currying.
  3. Functions are one-level, meaning that functions can be used as input and return values for other functions.

Together, these characteristics form a simple, expressive vocabulary for writing software that uses functions as its main building blocks. In other words, use function combinations to build software.

The classical combination of functions takes the output of one function as the input of another, for example, the combination f. g can be written as compose2 = f => g => x => f(g(x))

Here’s how to use it,

double = n => n * 2

inc = n => n + 1

compose2(double)(inc)(3)

The compose2 function takes the double function as the first argument and the inc function as the second, and then applies the combination of the two functions to parameter 3. Look again at compose2(), where f is double(), g is inc(), and x is 3. Function calls compose2(double)(inc)(3) are actually three different function calls,

  1. The first one, via double, returns a new function.
  2. The returned function uses inc and returns another new function.
  3. Another new function uses 3 and evaluates f(g(x)), that is, double(inc(3)).
  4. The value of x is 3, passed to inc().
  5. Inc (3) gets 4.
  6. Double (4) is 8.
  7. 8 is the return value of the whole function.

 

When software is combined, it can be represented by a combination graph. The following expressions can be intuitively expressed as:

Append = s1 => s2 => s1 + s2 append(‘ Hello, ‘)(‘ world! ‘)

The lambda calculus had a huge influence on software design, and before 1980, many very influential computer science brands used combinations of functions to build software. The table processing language (Lisp) was created in 1958 and was heavily influenced by the lambda calculus. Today, Lisp is the second oldest language still in widespread use.

I was introduced to it through AutoLISP: the scripting language used in the most popular Computer Aided Design (CAD) software: AutoCAD. AutoCAD is so popular, virtually every other CAD application supports AutoLISP so that they can be compatible. Lisp is also a popular teaching language in computer science curriculum for three reasons:

  1. Its simplicity makes it easy to learn the basic syntax and semantics of Lisp in about a day.
  2. Lisp is all about function composition, and function composition is an elegant way to structure applications.
  3. The best computer science text book I know of uses Lisp:Structure and Interpretation of Computer Programs.

I learned about LISP through AutoLISP, the scripting language used in AutoCAD, the most popular computer-aided software (CAD). AutoCAD is so popular that almost every other CAD application uses AutoLISP in order to be compatible with it. Lisp is also a popular teaching language in computer science courses for three reasons:

  1. Its simplicity makes it possible to learn the basic syntax and semantics of Lisp in about a day.
  2. Lisp is all about function composition, and function composition is the best way to build applications.
  3. I know that the best computer science textbook is one that uses Lisp: Structure and Interpretation of Computer Programs.

 

The fall of functional programming

In the 1970s and 1980s, the way software was built moved away from simple combinations and became a series of linear instructions for computers to follow. Then came object-oriented programming — a great idea about component encapsulation and messaging that was misinterpreted by popular programming languages as a bad idea about inheritance hierarchies.

Functional programming was relegated to academia: geeks, Ivy League professors, and lucky students escaped the Java spoon-feeding obsession between 1990 and 2010.

For most of us, software development has been a nightmare for 30 years. The Dark Ages.

 

The rise of functional programming

Around 2010, something great started to happen: JavaScript exploded. Before 2006, JS was widely regarded as a toy language for writing small animations in browsers, but it hid some powerful features, namely the λ calculus. People began to whisper about this new thing called functional programming.

By 2015, the idea of building software with combinations of functions became popular again. To make it simpler, the JS specification got its first major version update in a decade and added arrow functions, which made it easier to create and read functions, crease, and λ calculus.

Arrow functions are rocket fuel that makes functional programming in JS extremely popular. It’s rare today to see a large application that doesn’t use a lot of functional programming techniques.

Composition is a concise, elegant, and clear way to describe software behavior. The process of combining small, deterministic functions to create one large software component and function results in software that is easy to organize, understand, debug, extend, test, and maintain.

 

As you read the following articles, please put each example into practice. Remember to learn as a child: ask questions, explore, play and learn. Rediscover the joys you discovered as a child. Let’s do some magic.



comments

About the author:The mind is a flowering tree

Personal home page
My article
37