DEV Community

Discussion on: Functional Programming with JS

Collapse
 
peerreynders profile image
peerreynders • Edited

In the opposite, declarative programming we specify the program logic without describing the flow control

Looking at Wikipedia we find the following definition:

Declarative programming is often defined as any style of programming that is not imperative.

In my experience that is an incredibly bad definition (and perhaps even incorrect). Defining things entirely in terms what they are not is usually a sign of trouble.

Declarative programming typically lets you focus on describing what you want rather than describing how to get it.

SQL is a good example of declarative programming. This may seem confusing at first because aren't you telling the RDBMS "how to" join and intersect tables to get the data you want? No, that SQL is a description of the data you are interested in — you are not telling the RDBMS engine "how to get" the data — it will figure that out on it's own — but you are communicating what set of data you are interested in.

The reason functional programming is often considered declarative is because in languages like Haskell there is "little emphasis on explicit sequencing" — and sequencing is a big part of "control of flow".

In my opinion the first step to make your JavaScript "less imperative" is to shift focus away from "how things are done" to "what/why things need to be done". The simplest way to accomplish that is to stop relying on inline code and to name most if not all your functions in a way that reflects "what/why things need to be done".

While we all know "naming is hard" one doesn't get better by avoiding it — if you think of a better name later change it.

Seeing the function name explaining "what/why things need to be done" is more "declarative" than leaving the inline code in place which has to be mentally parsed again and again every time somebody reads the code.

But the real big difference between imperative and functional programming is "control of flow" and "transformation of values". Rich Hickey calls this the difference between:

  • Place-Oriented programming
  • Value-Oriented programming

So from that perspective your second code example should have been

const greeting = (name) => `Hi, ${name}`;

console.log(greeting('Ali'));
Enter fullscreen mode Exit fullscreen mode

i.e. greeting is the function that transforms the value 'Ali' to 'Hi, Ali' and that value is then passed to the run time system for display.

Imperative programming relies heavily on statements for flow of control while functional programming relies on expressions and functions for the transformation of values. Both expressions and functions have to produce a value (even if it's undefined) — statements do not.

Now given that out of the box JavaScript is mutable by default and doesn't support persistent data structures I think pursuing functional programming with it is a fool's errand (maybe look at ReScript instead) — though value-oriented programming can be often quite useful. I do believe that JavaScript is function-oriented. The existence of libraries is neither here nor there (you didn't mention immer) but in its core capacity as a browser automation language it should travel light and delegate as much work as possible to the browser's native code.

To enjoy the benefits of functional programming in JavaScript I'd look at the strategies that are employed in Rust — namely:

  • Don't modify what you intend to share.
  • Don't share what you intent to modify.

Unfortunately there is no borrowck in JavaScript to help manage ownership — there's only developer discipline. Controlled mutability in the right places (typically local) is your friend, mindless mutability is the enemy.