loading...
Cover image for Declarative Programming with JavaScript

Declarative Programming with JavaScript

adnanbabakan profile image Adnan Babakan (he/him) 惻3 min read

Hey there DEV.to community!

As you know, JavaScript is a pretty vast programming language. Meaning that it doesn't limit you to a specific paradigm, and you can implement almost every famous paradigm and go on with it.

This made me think about how can we go on with the declarative paradigm instead of imperative. In case you don't know what these words mean, here is a simple explanation: Imperative means you tell the compiler what you exactly want to happen, while in declarative paradigm you only specify what you want the result to be.

Declarative style is best followed in functional programming languages while it is pretty fun to follow this style in JavaScript.

Iteration through an array

Perhaps this sample will make it obvious for you what the difference between an imperative and a declarative paradigm is.

Usually what you'd do is to define a for loop as below:

let n = [-9, 87, 72, 452, 32, -9]
for(let i = 0; i < n.length; i++) {
    console.log(n[i])
}

This is called the imperative way. While by using forEach prototype of arrays, it is possible to rewrite this in a declarative way:

let n = [-9, 87, 72, 452, 32, -9]
n.forEach(v => console.log(v))

Both these codes have the same result, but the second one looks cleaner and more readable. Isn't it awesome?

Array mapping

Mapping is the action of applying a specific function to every item inside an array resulting in a new array.

Here is the imperative way:

let n = [-9, 87, 72, 452, 32, -9]
let z = []
let doubleMinusOne = x => (x * 2) - 1
for(let i = 0; i < n.length; i++) {
    z[i] = doubleMinusOne(n[i])
}

Now the z variable holds an array of items doubled and subtracted by one from the n array.

Here is how to do it declaratively:

let n = [-9, 87, 72, 452, 32, -9]
let z = n.map(v => (v * 2) - 1)

Very short and concise!

Array filtering

What if you wanted some items from an array matching a condition? Here is how you'd do it normally in an imperative way:

let n = [-9, 87, 72, 452, 32, -9]
let z = []
let lessThanFifty = v => v < 50
for(let i = 0; i < n.length; i++) {
    lessThanFifty(n[i]) && z.push(n[i])
}

And the code below is the declarative counterpart:

let n = [-9, 87, 72, 452, 32, -9]
let z = n.filter(v => v < 50)

KABOOM!

Reduce

This is the most amazing method ever existed and is very powerful! As the name suggests this method reduces array to a single value.

What if you wanted to have the summation of the numbers inside an array? What you'd probably do is as below:

let n = [-9, 87, 72, 452, 32, -9]
let s = 0
for(let i = 0; i < n.length; i++) {
    s += n[i]
}

Here is the magic of reduce!

let n = [-9, 87, 72, 452, 32, -9]
let s = n.reduce((acc, v) => acc + v)

The first argument of the function that reduce takes is called accumulation (or total) which holds the value of the previous value returned by the function. Each time we are adding the current value (second argument) to the accumulation.

The reduce method is not limited to summation only, and you can do almost everything!

let n = [-9, 87, 72, 452, 32, -9]
let m = n.reduce((acc, v) => acc * v)

Here is another awesome example. Finding the maximum (or minimum) value inside an array is simply possible by a simple algorithm:

let n = [-9, 87, 72, 452, 32, -9]
let maximum = n[0]
for(let i = 1; i < n.length; i++) {
    if(n[i] > maximum) maximum = n[i]
}

Although it is pretty simple, by using the reduce function it is possible to rewrite it in a declarative way which makes it very short (and professional-looking as well xD)!

let n = [-9, 87, 72, 452, 32, -9]
let maximum = n.reduce((max, v) => v > max ? v : max)
let minimum = n.reduce((min, v) => v < min ? v : min)

Given that you have a two-dimensional array and you want to flatten it. Here is the imperative way using a for loop:

let n = [[-9, 87], [72], 452, [32, -9]]
let flatten = []
for(let i = 0; i < n.length; i++) {
    if(Array.isArray(n[i])) flatten = flatten.concat(n[i])
    else flatten.push(n[i])
}

And now again! The power of reduce:

let n = [[-9, 87], [72], 452, [32, -9]]
let flatten = n.reduce((acc, v) => acc.concat(v), [])

The second argument passed to the reduce method (the empty array) is for the reduce method to know the initial value of the accumulation.


Hope you enjoyed this article!

Posted on by:

adnanbabakan profile

Adnan Babakan (he/him)

@adnanbabakan

I'm Adnan Babakan and I'm from Iran. I started programming since I was 8 and now I'm 19. I love programming!

Discussion

markdown guide