Imperative vs Declarative


Short post today, simple premise:

Try to be declarative if possible.

Small aside:

One of the reasons I started writing about programming is that most of the tech blogs I enjoy tend to provide examples in “cool” languages - Rust, Go, Lisp, etc.

However, most of us are stuck writing in Enterprise Approved™ languages, so I thought it would be neat to write about the mostly uncool languages I’m familiar with *cough Java*.

Anyways, here is what I mean by imperative vs declarative.

Objective:

  1. Find a name in a list.
  2. Print it, if it exists.

We’re going to try two different styles to achieve this. Which one do you prefer?

import java.util.List;
import java.util.stream.*;

public class Demo {

  public static void main(String[] args) {
    var names = List.of(
      "Bob Yancy",
      "Tyler Lawton",
      "Nancy McSweeny",
      "Karl Plunk"
    );

    /* Imperative */
    var name = "";
    for (String s : names) {
      if (s.contains("Tyler")) {
        name = s;
      }
    }

    if (!name.isEmpty()) {
      System.out.println(name);
    }

    /* Declarative */
    names
      .stream()
      .filter(str -> str.contains("Tyler"))
      .findFirst()
      .ifPresent(System.out::println);
  }
}

The declarative style wins for me.

  • The chain of operations reads almost like English.
  • The intent, which is to print something if it’s found, is fully encapsulated.
  • No intermediate variables, no scope change, no mutation.

The imperative style is also readable, but it’s clunky.

  • I have to instantiate an intermediate variable, name.
  • I have to track the mutation of the name variable.
  • The intent, which is to print something if it’s found, is not encapsulated - it’s spread across several scopes.

This may seem like a trite example, but that’s kind of the point.

It’s an easy, quick win to write code in the declarative style if you have the option, and it compounds into a net benefit in a larger codebase.