DEV Community

loading...
Cover image for Declarative Programming with JavaScript

Declarative Programming with JavaScript

Adnan Babakan (he/him)
I'm Adnan Babakan and I'm from Iran. I started programming since I was 8 and now I'm 20. I love programming!
Updated on ・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 we can 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])
}
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

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])
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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])
}
Enter fullscreen mode Exit fullscreen mode

And the code below is the declarative counterpart:

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

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]
}
Enter fullscreen mode Exit fullscreen mode

Here is the magic of reduce!

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

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)
Enter fullscreen mode Exit fullscreen mode

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]
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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])
}
Enter fullscreen mode Exit fullscreen mode

And now again! The power of reduce:

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

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!

Discussion (0)