“A close-up of white dials on a music mixer” by Alexey Ruban on Unsplash

Function Composition point-free style

Salama Ashoush
tajawal
5 min readMay 10, 2018

--

A functional glimpse in JavaScript

What is a function?

A function is something that map an input to an output

// addOne is a function
function addOne(x){
return x + 1;
}
// more like a procedure not a real function (Mathematics)
// not everything using function keyword is a real function
// this also doing a bad practice as we will see
function something(){
console.log("i am a fake function");
}

now you know what is a real function, let's know more about functions in a functional programming world especially two important concepts :

1. First class functions:

When we say functions are “first class”, we mean they are just like everything else.

We can treat functions like any other data type and there is nothing particularly special about them — they may be stored in arrays, passed around as function parameters, assigned to variables, etc.

const hi = name => `Hi ${name}`; // as a normal value
const greeting = name => hi(name); // returned from a function

you may know about the concept callbacks or anonymous functions in JavaScript, these concepts existing because functions in javascript are first-class citizens like any other values

// callbacks
const getServerStuff = callback => ajaxCall(json => callback(json));
// same as above
const getServerStuff = ajaxCall;

in pure functional programming languages like Haskell, everything is an expression even the program itself

2. Pure functions

A pure function is a function that, given the same input, will always return the same output and does not have any observable side effects

const xs = [1,2,3,4,5];// impure
xs.splice(0,3); // [1,2,3]

xs.splice(0,3); // [4,5]
// pure
xs.slice(0,3); // [1,2,3]

xs.slice(0,3); // [1,2,3]


// impure
const minimum = 21;
const checkAge = age => age >= minimum;

// pure
const checkAge = (age) => {
const minimum = 21;
return age >= minimum;
};

Side effects may include, but are not limited to

  • changing the file system
  • inserting a record into a database
  • making an HTTP call
  • mutations
  • printing to the screen/logging
  • obtaining user input
  • querying the DOM
  • accessing system state

you may wonder what is the purpose of a program that doesn't change anything …. well, there are ways to do such thing in a pure way like IO Monads

so now you know what is a function let’s talk about another important thing that plays a key role in function composition

Function Currying:

The concept is simple: You can call a function with fewer arguments than it expects. It returns a function that takes the remaining arguments.

const add = x => y => x + y;
const increment = add(1);
const addTen = add(10);

increment(2); // 3
addTen(2); // 12

in languages like Haskell all function are automatically curried, but let write our first functional utility curry it takes any function to convert it to a curried function this is possible in javascript because of recursion and closures

function curry(fn) {
const arity = fn.length;

return function $curry(...args) {
if (args.length < arity) {
return $curry.bind(null, ...args);
}

return fn.call(null, ...args);
};
}

libraries like lodash or ramda include these utilities so you don't need to write it yourself, so let use it

const match = curry((what, s) => s.match(what));
const replace = curry((what, replacement, s) => s.replace(what, replacement));
const filter = curry((f, xs) => xs.filter(f));
const map = curry((f, xs) => xs.map(f));

a curried function is the concept that allows us to partially apply a function

In math calling a function is called “Applying a function” so partially calling function with fewer params called “Partial Application” and it is a common concept in functional world

oh, beautiful isn't it, now let's talk about composting of functions

Function Composition:

a composition is mixing more than one small function to make a bigger one

const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;
const shout = x => toUpperCase(exclaim(x))

shout('send in the clowns'); // "SEND IN THE CLOWNS!"
function composition

so if you have a function f and function g composing them like g . f , the dot means f after g and these must be associative g.f === f.g that means it doesn't matter if you call f first or g first, they should be the same and functions bowered this property from functions in math, now let write another utility to make composition easier compose

function compose(...fns) {
const n = fns.length;

return function $compose(...args) {
let $args = args;

for (let i = n - 1; i >= 0; i -= 1) {
$args = [fns[i].call(null, ...$args)];
}

return $args[0];
};
}

compose function takes any number of functions and compose them from right to left

const head = x => x[0];
const reverse = reduce((acc, x) => [x].concat(acc), []);
const last = compose(head, reverse);

last(['jumpkick', 'roundhouse', 'uppercut']); // 'uppercut'

there are other shapes of compose composeLeft , composeRight you can find them in libraries we mentioned before

Pointfree:

Pointfree style means functions that never mention the data upon which they operate. First class functions, currying, and composition all play well together to create this style.

// not pointfree because we mention the data: word
const snakeCase = word => word.toLowerCase().replace(/\s+/ig, '_');

// pointfree
const snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase);

Let’s look at another example.

// not pointfree because we mention the data: name
const initials = name => name.split(' ').map(compose(toUpperCase, head)).join('. ');
// pointfree
const initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));
initials('hunter stockton thompson'); // 'H. S. T'

we just scratched the surface of composing functions and you may wonder where all of these rules and concepts come from, off-course it rooted by a mathematical theory and that math proved for hundreds of years before even computers math areas like Lambda calculus, Category theory is one of the main roots behind our beautiful world of functions

Reference:

https://mostly-adequate.gitbooks.io/mostly-adequate-guide/

--

--