Categories
Functional Javascript

How to do image resizing without ImageMagick with Node.js?

To do image resizing without ImageMagick with Node.js, we use the lwip package.

To use it we write

require("lwip").open("image.jpg", (err, image) => {
  image
    .batch()
    .scale(0.75)
    .rotate(45, "white")
    .crop(200)
    .blur(5)
    .writeFile("output.jpg", (err) => {
      //...
    });
});

to call open to open image.jpg for resizing.

Then we call scale to resize it to 75% its original size.

We rotate by 45 degrees clockwise with rotate and fill the space with white.

Then we call crop to crop it to 200px by 200px.

Next we call blur to blur the image.

And we call writeFile to write the modified image to output.jpg.

We can get errors from err in the callback.

Categories
Functional Javascript

Functional Programming Concepts in JavaScript

Functional programming is a programming paradigm which states that we create computation as the evaluation of functions and avoid changing state and use mutable data.

In JavaScript, we can apply these principles to make our programs more robust and create fewer bugs.

In this article, we’ll look at how to apple some functional programming principles in our JavaScript programs, including pure functions and creating immutable objects.

Pure Functions

Pure functions are functions that always return the same output given the same set of inputs.

We should use pure functions as much as possible because they’re easier to test and the output is always predictable given a set of inputs.

Also, pure functions don’t create any side effects, which means that it does change anything outside the function.

An example of a pure function would be the following add function:

const add = (a, b) => a + b;

This function is a pure function because if we pass in 2 numbers, we’ll get the 2 numbers added together returned.

It doesn’t do anything outside the function, and it doesn’t have values that change the returned value inside the function.

Example of functions that aren’t pure functions include:

let x;
const setX = val => x = val;

setX isn’t a pure function because it sets the value of x which is outside the function. This is called a side effect.

A side effect is state change that’s observed outside the called function other than its returned value. setX sets a state outside the function, so it commits a side effect.

Another example would be the following:

const getCurrentDatePlusMs = (milliseconds) => +new Date() + milliseconds;

getCurrentDatePlusMs returns a value that depends on +new Date() which always changes, so we can check the value of it with tests easily. It’s also hard to predict the return value given the input since it always changes.

getCurrentDatePlusMs isn’t a pure function and it’s also a pain to maintain and test because of its ever-changing return value.

To make it pure, we should put the Date object outside as follows:

const getCurrentDatePlusMs = (date, milliseconds) => +date + milliseconds;

That way, given the same date and milliseconds, we’ll always get the same results.

Immutability

Immutability means that a piece of data can’t be changed once it’s defined.

In JavaScript, primitive values are immutable, this includes numbers, booleans, strings, etc.

However, there’s no way to define an immutable object in JavaScript. This means that we have to be careful with them.

We have the const keyword, which should create a constant by judging from the name of it, but it doesn’t. We can’t reassign new values to it, and we can’t redefine a constant with the same name.

However, the object assigned to const is still mutable. We can change its properties’ values, and we can remove existing properties. Array values can be added or removed.

This means that we need some other way to make objects immutable.

Fortunately, JavaScript has the Object.freeze method to make objects immutable. It prevents property descriptors of an object from being modified. Also, it prevents properties from being deleted with the delete keyword.

Once an object is frozen, it can’t be undone. To make it mutable again, we have to copy the object to another variable.

It applies these changes to the top level of an object. So if our object has nesting, then it won’t be applied to the nested objects.

We can define a simple recursive function to do freeze level of an object:

const deepFreeze = (obj) => {
  for (let prop of Object.keys(obj)) {
    if (typeof obj[prop] === 'object') {
      Object.freeze(obj[prop]);
      deepFreeze(obj[prop]);
    }
  }
}

The function above goes through every level of an object and calls Object.freeze on it. This means it makes the whole nested object immutable.

We can also make a copy of an object before manipulating it. To do this, we can use the spread operator, which works with objects since ES2018.

For example, we can write the following function to make a deep copy of an object:

const deepCopy = (obj, copiedObj) => {
  if (!copiedObj) {
    copiedObj = {};
  }

  for (let prop of Object.keys(obj)) {
    copiedObj = {
      ...copiedObj,
      ...obj
    };
    if (typeof obj[prop] === 'object' && !copiedObj[prop]) {
      copiedObj = {
        ...copiedObj,
        ...obj[prop]
      };
      deepCopy(obj[prop], copiedObj);
    }
  }
  return copiedObj;
}

In the code above, we create a new copiedObj object to hold the properties of the copied object if it doesn’t exist yet, which shouldn’t in the first call.

Then we loop through each property of the obj object and then apply the spread operator to copiedObj and obj to make a copy of the values at a given level. Then we do this recursively at every level until we went through every level, then we return the final copiedObj .

We only apply the spread operator if the property doesn’t exist at that level yet.

How do we know that this works? First, we can check if properties of each value are the same, which it is if we run console.log on it. Then we can also check with the === if the copied object has the same reference as the original object.

For example, if we have:

const obj = {
  foo: {
    bar: {
      bar: 1
    },
    a: 2
  }
};

Then we can check by writing:

const result = deepCopy(obj);
console.log(result);

To check the content of result .

We should get:

{
  "foo": {
    "bar": {
      "bar": 1
    },
    "a": 2
  }
}

This is the same as obj . If we run:

console.log(result === obj);

we get false , which means the 2 aren’t referencing the same object. This means that they’re a copy of each other.

Pure functions and immutability are important parts of functional programming. These concepts are popular for a reason. They make outputs predictable and make accidental state changes harder.

Pure functions are predictable since they return the same output for the same set of inputs.

Immutable objects are good because it prevents accidental changes. Primitive values in JavaScript are immutable, but objects are not. We can freeze it with the Object.freeze method to prevent changes to it and we can also make a copy of it recursively with the spread operator.

Categories
Functional Javascript

Functional JavaScript — Piping and Functors

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 pipe functions and functors with JavaScript.

Pipe

We can create a pipe function by creating a function that takes an array of functions as arguments.

It returns a function that takes a value and we call reduce on it with that calls fn with acc .

For example, we can write:

const compose = (...fns) =>
  (value) =>
  fns.reduceRight((acc, fn) => fn(acc), value)

The only difference is that we used reduceRight instead of reduce so that we don’t have to call reverse to apply all the functions.

Composition is Associative

Composition is associative, this means we can rearrange the parentheses of our operations

For instance:

compose(f, compose(g, h)) == compose(compose(f, g), h)

returns true .

Functors

Functor is a plain object that implements the function map while running River each value to produce a new object.

A functor is a container that holds some value in it.

For example, we can write:

const Container = function(val) {
  this.value = val;
}

to create our container.

Then we can use new to invoke the Container constructor:

let foo = new Container(3);

We can create a Container.of property to add a container to let us return a Container instance:

const Container = function(val) {
  this.value = val;
}

Container.of = function(value) {
  return new Container(value);
}

We added the of static method to return a Container instance.

The of method just gives us an alternative to using the new operator to create the Container instance.

Then we can create a Container instance with the of method:

const nested = Container.of(Container.of(1));

Then we’ll see the nested Container instances.

Functor Implements Method Called map

Functors implement the map method.

We can add it as an instance method by adding it to the prototype property:

const Container = function(val) {
  this.value = val;
}

Container.of = function(value) {
  return new Container(value);
}

Container.prototype.map = function(fn) {
  return Container.of(fn(this.value));
}

Then we can use the map method after we create a Container instance.

For instance, we can use it by writing:

const squared = Container.of(3).map(a => a ** 2);

Then squared is a Container instance with value being 9.

We call map repeatedly to repeat an operation.

So we can write:

const squared = Container.of(3)
  .map(square)
  .map(square)
  .map(square);

Then squared is a Container instance with value being 6561.

Functor is just an object that implements a map method.

Conclusion

Functors are plain objects that have value.

The object has a map method.

We can pipe functions to call multiple functions and get the returned value.

Composition is associative, so we can rearrange the parentheses of our operations.

Categories
Functional Javascript

Functional JavaScript — Partial Application and Composition

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 partial application and composition of functions with JavaScript.

Partial Application

Partial application is where we only apply some of the arguments that are expected in a function.

For example, if we have a function with 3 parameters:

const add = (x, y, z) => x + y + z;

Then we can create a function that has the add function with arguments partially applied by writing:

const add1 = (y, z) => add(1, y, z);

Then we can use it by writing:

const sum = add1(2, 3);

And we get 6.

To generalize this, we can write:

const partial = function(fn, ...partialArgs) {
  let args = partialArgs;
  return function(...fullArguments) {
    return fn(...[...partialArgs, ...fullArguments]);
  };
};

We create our own partial function by returning a function with the partialArgs and fullArguments spread as arguments into the fn function.

Then we can use it by writing:

const sum = partial(add, 1)(2, 3);

and sum is 6 again.

Currying vs. Partial Application

Currying is good whenever we need to convert functions that take multiple arguments to multiple functions that take one argument.

Situations where we need to convert a function that takes multiple arguments to a callback for map that only takes one parameter an example of that.

Partial application of a function is useful for any situation where we need to apply one or arguments to a function and return a function that has the arguments applied.

Composition

Composition is where we chain multiple function calls to return the result that we want.

We have many functions that do one thing, and we combine them into one so that we can get the result we want.

For instance, we can compose the array map and filter methods by writing:

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

And arr is [1, 9] .

We call filter to return an array with only the odd numbers.

And then we call map to square each odd number.

compose Function

We can generalize the compose function by writing:

const compose = (fn1, fn2) =>
  (c) => fn1(fn2(c))

Our function takes 2 functions as parameters and then we return a function that calls one after the other.

fn2 is called first, then fn1 is called on the result returned by fn2 .

Then we can use it by writing:

let number = compose(Math.round, parseFloat)('10.1')

We called compose with Math.round and parseFloat .

parseFloat is called first with '10.1' and then Math.round is called on the returned result.

Then number is 10.

Compose Many Functions

We can create a general version of the compose function by using the array reduce method.

For example, we can write:

const compose = (...fns) =>
  (value) =>
  fns.reverse().reduce((acc, fn) => fn(acc), value)

We created a function which takes an array of functions fns as a parameter.

Then we return a function that takes a value as the initial value and call reduce on it to call each function in the array with the returned result.

acc is the returned result from calling the functions so far, and fn is the function.

And then we can use it by writing:

let splitIntoSpaces = (str) => str.split(" ");
let count = (array) => array.length;
const countWords = compose(count, splitIntoSpaces)('foo bar baz');

We split the string by the space with splitIntoSpaces function.

And we get the length of the split string array with the count function.

And then we use compose to combine them together.

Once we call the returned function with a string, we get the number words separated by a space.

So countWords is 3.

Conclusion

We can partially apply and compose functions with JavaScript.

Partial application lets us call functions with some arguments applied.

And composition lets us call multiple functions in a chain.

Categories
Functional Javascript

Functional JavaScript — Monads

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 pipe functions and functors with JavaScript.

MayBe Functors

A MayBe functor is one that lets us implement a map function in a different way.

We start off by creating a constructor that stores a value:

const MayBe = function(val) {
  this.value = val;
}

MayBe.of = function(val) {
  return new MayBe(val);
}

Then we add the methods unique to the MayBe functor.

We have the isNothing method to check if this.value has anything.

The map method will return something different depending on whether this.value has something or not.

We add:

MayBe.prototype.isNothing = function() {
  return (this.value === null || this.value === undefined);
};

MayBe.prototype.map = function(fn) {
  return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this.value));
};

Together, we have:

const MayBe = function(val) {
  this.value = val;
}

MayBe.of = function(val) {
  return new MayBe(val);
}

MayBe.prototype.isNothing = function() {
  return (this.value === null || this.value === undefined);
};

MayBe.prototype.map = function(fn) {
  return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this.value));
};

Then we can use it by writing:

const str = MayBe.of("foo").map((x) => x.toUpperCase())

Then we get the the value property of the MayBe instance is 'FOO' .

If this.value is null or undefined , then map will return a MayBe functor with value being null .

So if we have something like:

const str = MayBe.of("james")
  .map(() => undefined)
  .map((x) => `Mr. ${x}`)

We’ll get the final value of value being null instead of throwing an error.

Either Functor

The Either functor allows us to solve problems with branches.

We create a Nothing or Some functor and out them in an object.

So we write:

const Nothing = function(val) {
  this.value = val;
};

Nothing.of = function(val) {
  return new Nothing(val);
};

Nothing.prototype.map = function(f) {
  return this;
};

const Some = function(val) {
  this.value = val;
};

Some.of = function(val) {
  return new Some(val);
};

Some.prototype.map = function(fn) {
  return Some.of(fn(this.value));
}

Now if want to hold some data, then we can use the Some functor.

Otherwise, we use the Nothing functor to hold some non-existent value.

Monads

A monad is a functor with a chain method.

The chain method calls a join method to call it return an a MayBe instance if this.value has a value.

For example, we can write:

const MayBe = function(val) {
  this.value = val;
}

MayBe.of = function(val) {
  return new MayBe(val);
}

MayBe.prototype.isNothing = function() {
  return (this.value === null || this.value === undefined);
};

MayBe.prototype.map = function(fn) {
  return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this.value));
};

MayBe.prototype.join = function() {
  return this.isNothing() ? MayBe.of(null) : this.value;
}

MayBe.prototype.chain = function(f) {
  return this.map(f).join()
}

The join method checks if this.value is null or undefined .

If it is, then we return a null MayBe functor.

Otherwise, we return this.value .

chain just calls map and join together.

This way, if we map something to null , then it stays null .

Then we can use this by writing:

let mayBe = MayBe.of({
  data: [{
    title: 'foo',
    children: [{
      bar: 2
    }]
  }]
})

let ans = mayBe.map((arr) => arr.data)
  .chain((obj) => map(obj, (x) => {
    return {
      title: x.title
    }
  }))

then we get the title from the object we passed into of .

Conclusion

A monad is a functor that has the chain method, which does the mapping and joining together.