Categories
Functional Javascript

Functional JavaScript — The Basics

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to use the functional programming features in JavaScript.

What Is Functional Programming?

Functional programming is the use of various principles in our app’s code.

The most basic principle is that we abstract out the how part into reusable code.

And we create functions that don’t depend on the outside.

Also, if the function have the same input, we get the same output.

Functions are mathematical functions.

They take arguments and return values.

The arguments we pass in will always create the same output if the arguments are the same.

Also, they don’t interact with the outside world.

For instance, we can have a function like:

const calculateTax = (value, percentValue) => {
  return value / 100 * (100 +
    percentValue)
}

It takes some arguments and doesn’t reference anything outside in the function body.

This is called a pure function.

A pure function is a function that doesn’t reference anything outside.

And if we give it the same inputs, it’ll always give the same outputs.

JavaScript Functions vs Methods

A function is a piece of code that can be called by its name.

It can pass arguments and return values.

A method is a piece of code that may be called by its name with its associated object name.

So a function is something like:

const foo = (a) => {
  return a
}

And a method is something like:

const obj = {
  foo: (a) => {
    return a
  }
}

We call the method by writing:

obj.foo(1)

Referential Transparency

Functions return the same output for the same input.

This property is called referential transparency.

If we have referential transparent, then we can infer the return value from the function call.

So if we have:

const sameVal = (i) => {
  return i
}

and:

sum(4,5) + sameVal(1)

We can infer that the expression above is the same as:

sum(4,5) + 1

The substitution model lets us substitute the direct result of a function.

This leads to parallel code and caching since they don’t depend on anything outside.

All they depend on is their argument.

Imperative, Declarative, Abstraction

Functional programming is about being declarative and writing abstracted code.

Declarative code means we tell the computer what the compiler needs to do rather than how to do it.

The how part is abstracted into higher-order functions.

Higher-order functions are fuincti8ons that take functions as arguments or return functions.

For example, the array instance forEach method takes a callback and then log an element.

We can iterate through an array with it by writing:

const array = [1, 2, 3];
array.forEach((a) => console.log(a))

Conclusion

Functional programming follows some basic principles.

We create functions that don’t depend on the outside and if we give them the same inputs, we always get the same outputs.

Categories
Functional Javascript

Functional JavaScript — Higher-Order Functions in the Real World

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to use higher-order functions.

Higher-Order Functions in the Real World

Higher-order functions are used in the real world a lot.

For example, arrays have many instance methods that are higher-order functions.

One of them is the every method.

every takes a callback that returns the boolean expression to check if each item is what we’re looking for.

For example, we can use it by writing:

const allEven = [1, 2, 3].every(a => a % 2 === 0);

We pass in a callback to check if each entry is evenly divisible by 2.

This should return false since we have 1 and 3 which are odd.

Also, the every method can be implemented with our own code:

const every = (arr, fn) => {
  for (const a of arr) {
    if (!fn(a)) {
      return false;
    }
  }
  return true;
}

We loop through the entries of arr and then call fn to check if the entry matches the given condition.

If it does, then we return false since we have at least one item that doesn’t match the given we have in the callback.

We can use it by writing:

const allEven = every([1, 2, 3], a => a % 2 === 0)

And allEven should be false .

some Function

The some method is similar to every .

It’s also part of the array instance.

For example, we can call the array instance’s some method by writing:

const hasEven = [1, 2, 3].some(a => a % 2 === 0)

We call the some method on the array.

The callback returns the condition and that we’re looking for.

It checks if at least one item matches the given condition.

Therefore, hasEven should be true since 2 is even.

Also, we can implement it in our own way.

For example, we can write:

const some = (arr, fn) => {
  for (const a of arr) {
    if (fn(a)) {
      return true;
    }
  }
  return false;
}

We loop through the items and check if fn(a) returns true .

If one does, then we return true .

Otherwise, we return false .

We can call our own some function by writing:

const hasEven = some([1, 2, 3], a => a % 2 === 0)

then we get true .

We pass in the array and the callback function that returns the function we’re checking for.

sort

The array instance sort method takes a function that lets us compare 2 entries and sort them.

The callback takes 2 parameters, which are 2 entries of the array.

If the first parameter should come before the second, then we return a negative number.

If we keep the same order, then we return 0.

Otherwise, we return a positive number.

We can improve this by creating a function that returns a comparator function.

For example, we can write:

const sortBy = (property) => {
  return (a, b) => a[property] - b[property];
}

const arr = [{
    foo: 3
  },
  {
    foo: 1
  },
  {
    foo: 2
  }
]

const sorted = arr.sort(sortBy('foo'));
console.log(sorted);

We have the sortBy function that returns a function to let us compare a property value.

Then we call arr.sort with our sortBy function, which returns the comparator function for the property we want.

Then sorted should be:

[
  {
    "foo": 1
  },
  {
    "foo": 2
  },
  {
    "foo": 3
  }
]

We can see the items are sorted.

Conclusion

We can implement various array methods our way.

There are many applications of higher-order functions in the real world.

Categories
Functional Javascript

Functional JavaScript — Higher-Order Functions

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to use higher-order functions.

Higher-Order Functions

Higher-order functions are functions that take other functions as arguments and return a function.

It also takes other data and let us manipulate them.

JavaScript Data Types

JavaScript has several data types.

They include numbers, strings, booleans, objects, null and undefined .

Functions are data types like strings.

We can pass them around, store them as variables, etc.

This means they act like any other data type.

Storing a Function

We can store a function in a variable.

For example, we can write:

let fn = () => {}

Then we can check its type by using the typeof operator:

typeof fn

We should get 'function' returned with that.

Passing a Function

Functions can have parameters.

So we can write:

const getType = (arg) => {
  console.log(typeof arg)
}

We get the type by using the typeof operator from the arg .

We can also make our function call a function that’s passed in.

To do that, we can check if we passed in a function to our function.

For example, we can write:

const getType = (arg) => {
  if (typeof arg === "function") {
    arg()
  } else {
    console.log(arg)
  }
}

to check if arg is a function.

If it’s a function, we call it.

Otherwise, we log its value.

Returning a Function

We can return a function inside a function.

For instance, we can write:

let crazy = () => {
  return Number
}

We return the built-in Number function in our function.

Also, we can call the returned function.

So we can write:

let fn = crazy();
fn("abc");

We call the function returned by crazy .

Then we call fn and return the value that it returns.

Abstraction and Higher-Order Functions

We can abstract the higher-order functions by getting the function from the parameter and calling it.

For example, we can write:

const forEach = (array, fn) => {
  for (const a of array) {
    fn(a);
  }
}

fn is a function, so we can call it.

We loop through the array array and call fn with each entry of array as an argument.

Then we can use it by writing:

forEach([1, 2, 3], (data) => {
  //...
})

We have the array as the first argument.

The 2nd argument is a function that we call on each item.

forEach traverses the array and do what we want with it.

Also, we can do the same with an object by writing:

const forEachObj = (obj, fn) => {
  for (const [key, value] of Object.entries(obj)) {
    fn(key, value);
  }
}

forEach({
  a: 1,
  b: 2,
  c: 3
}, (key, value) => {
  //...
})

We created the forEachObj function which takes an object and a function as parameters.

Then we loop through the key-value pairs with the Object.entries method and call the fn function on each key and value .

Conclusion

We can create higher-order function getting a function and then calling it with a function.

This can be done easily for code that traverses arrays and objects.

Categories
Functional Javascript

Functional JavaScript — Functional Programming and Arrays

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to create our own array methods.

Working Functionally on Arrays

Array functions are useful for manipulating arrays.

There are many built-in array methods like map and forEach .

Many of them take callbacks which let us do something with the array entries.

map

The map method lets us convert array entries from one thing to another.

To implement it, we can loop through each entry and call a function that we pass in.

The function’s returned value will be pushed into a new array and returned.

For example, we can write:

const map = (array, fn) => {
  const results = []
  for (const a of array) {
    results.push(fn(a));
  }
  return results;
}

The map function takes an array and fn function.

We use the for…of loop to loop through the entries.

fn is used to map a value from one to another value.

Then we push the returned item in the results .

And we return the results array.

Then we can use it by writing:

const arr = map([1, 2, 3], (x) => x ** 3);

Then arr is:

[1, 8, 27]

filter

We can implement our own filter function which lets us return a new array with entries that meets a given condition.

The condition is in the callback.

For example, we can write:

const filter = (array, fn) => {
 let results = [];
  for (const a of array) {
    if (fn(a)) {
      results.push(a)
    }
  }
  return results;
}

We loop through the array with a for…of loop.

Then we check with the fn function with the argument a whether it returns true or not.

If it returns true , then we push the item a into results .

Once we looped through all the items, we return results .

Then we can use it by writing:

const arr = filter([1, 2, 3], a => a % 2 === 1);

Then we get:

[1, 3]

as the value of arr .

Chaining Operations

We can chain the 2 operations since they’re both pure functions.

For instance, we can filter our items and then map them to the values of our choice:

const map = (array, fn) => {
  const results = []
  for (const a of array) {
    results.push(fn(a));
  }
  return results;
}

const filter = (array, fn) => {
  let results = [];
  for (const a of array) {
    if (fn(a)) {
      results.push(a)
    }
  }
  return results;
}

const arr = map(filter([1, 2, 3], a => a % 2 === 1), a => a ** 3);

We first called the filtet function to return an array of odd numbers.

Then we cube all the odd numbers and return the array of cubed odd numbers.

So arr is:

[1, 27]

We can rewrite that in a cleaner way by writing:

const odd = filter([1, 2, 3], a => a % 2 === 1);
const arr = map(odd, a => a ** 3);

Conclusion

We can create our own map and filter functions to map array entries and return a filtered array.

Categories
Functional Javascript

Functional JavaScript — Functional Array Methods

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to create our own array methods.

concatAll

We can create our own concatAll method to concatenate all the nested array into one big array.

For example, we can write:

const concatAll = (arrays) => {
  let results = []
  for (const array of arrays) {
    results = [...results, ...array];
  }
  return results;
}

We just spread the array entries of all the arrays and then return the resulting array.

Then we can use it to unnest nested arrays.

For example, we can write:

const arr = concatAll([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]);

Then arr is:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Reducing Function

Reduce is a function that lets us combine the entries of an array into a single value.

To create our own reduce function, we can write:

const reduce = (array, fn) => {
  let accumlator = 0;
  for (const a of array) {
    accumlator = fn(accumlator, a)
  }
  return accumlator;
}

The reduce function takes an array and a fn function.

array is the array we loop through to combine the values from the array and assign it as the value of accumulator .

fn returns a value with the accumulator and a values combined into one with some operations.

Once we looped through the array, then we return the accumulator value.

Then we can use it to add the numbers in the array by writing:

const sum = reduce([1, 2, 3, 4, 5], (acc, val) => acc + val)

We pass in a number array and a callback to combine the entries of the array together.

Then sum is 15 since we added all the numbers together.

We can make the reduce function more robust by accepting an initial value for accumulator .

For example, we can write:

const reduce = (array, fn, initialValue) => {
  let accumlator = initialValue;
  for (const a of array) {
    accumlator = fn(accumlator, a)
  }
  return accumlator;
}

We assign the initialValue as the initial value of accumulator .

This way, we don’t assume that we’re always working with number arrays.

Zipping Arrays

We can zip multiple arrays into one.

We create the entry for each array with our own function.

And then we push that into the array we return.

We only loop up to the length of the shortest array, so the returned array will also have the same length as the shortest array.

For example, we can write:

const zip = (leftArr, rightArr, fn) => {
  let index, results = [],
    length = Math.min(leftArr.length, rightArr.length);
  for (index = 0; index < length; index++) {
    results.push(fn(leftArr[index], rightArr[index]));
  }
  return results;
}

We created a zip function with the leftArr , rightArr , and fn parameters.

leftArr and rightArr are arrays and fn is a function.

We loop through the shortest length, which is the length .

In the loop body, we push the zipped entry to the results array.

Once we did that, we return results .

Then we can use that by writing:

const zipped = zip([1, 2, 3, 4], ['foo', 'bar', 'baz'], (a, b) => `${a} - ${b}`)

We have a callback to combine the entry from the left and right together into a string.

Then zipped is:

["1 - foo", "2 - bar", "3 - baz"]

Conclusion

We can unnest arrays and zip them together with our own functions.