Functional Primer, Part 4 – Practice & Explore

Functional programming is a broad discipline, and this series has only scratched the surface. Like most skills, it is learned through practice. To help you practice, I’ve found a few ideas that are rooted in functional programming and may find a place in your next project. I’ve also collected a few functional languages that offer a chance to further explore functional programming.

Functional Concepts

I wanted to review two interesting higher-level functional programming concepts that you can explore. These ideas can be a good way to integrate FP thinking into your daily routine, without changing what you’re working on.

Monads

Monads are one of the most infamous concepts in functional programming. They can be confusing to understand because they’re so broad that you’ve already used them without realizing it. Instead of trying to explain them myself, I’ll share two resources that helped me get a grasp on monads:

Functional core, imperative shell

Functional core, imperative shell is an architecture pattern that mixes functional programming with imperative programming in an attempt to cancel out the downsides of each. Functional languages are known to be weak when interacting with the “real world,” A.K.A. user input or other IO.

With this pattern, you write the core of your application logic with functional patterns, benefiting from easier testability and developer experience. Then, you write the exterior layers of your application with an imperative style, which is better at handling IO.

I learned of this pattern from Gary Bernhardt and his Destroy All Software screencast. He does a great job of explaining the pattern and offers a helpful collection of other technical screencasts.

Functional Languages

JavaScript is the language that I used for all of my examples, but JavaScript supports non-functional programming. As an alternative, I’ve collected a list of my favorite functional languages to help you dive into functional programming and remove some productivity obstacles.

Haskell

Haskell is a popular, purely functional language that’s a member of the ML family of programming languages, with a number of interesting features. One of those is lazy evaluation, a unique feature that allows Haskell to work with infinite data structures, but only evaluates the part of the data structure that’s used. Haskell also supports a strong static type system that’s rooted in mathematics.

Here’s a small snippet of Haskell demonstrating a recursive maximum function.


maximum' :: (Ord a) => [a] -> a  
maximum' [] = error "maximum of empty list"  
maximum' [x] = x  
maximum' (x:xs) = max x (maximum' xs) 

If you’re interested in learning Haskell, Learn You a Haskell For Great Good is a wonderful resource.

Elixir

Elixir is another functional language that’s gained a lot of popularity recently. This language is built on top of the Erlang VM, and it looks a lot like Ruby. The VM’s most noteworthy feature is that it supports a super-lightweight concurrency method, allowing you to (more) easily translate your assortment of functions into concurrent applications.

Here’s a small snippet of Elixir from the official docs that demonstrates some basic recursion.


defmodule Recursion do
  def print_multiple_times(msg, n) when n <= 1 do
    IO.puts msg
  end

  def print_multiple_times(msg, n) do
    IO.puts msg
    print_multiple_times(msg, n - 1)
  end
end

Recursion.print_multiple_times("Hello!", 3)

I don’t have any experience with these resources, but the Elixir website has a list of recommended books and websites to learn Elixir.

Lisp

Lisp is arguably one of the most famous functional programming languages out there, inspiring a family of languages, including Scheme, Racket, and Clojure. Lisp’s distinct syntax of surrounding every expression with parentheses has frustrated many programmers with a lost closing paren. I think the language’s usefulness outweighs any parenthetical frustration.

Here’s an example of Lisp showing off a recursive function that checks for a number in a list.

(defun n-in-list (n the-list)
                      (cond ((null the-list) nil)
                        ((equalp n (first the-list)) t)
                         (t (n-in-list n (rest the-list)))))

Structure and Interpretation of Computer Programs from MIT, AKA “The Wizard Book,” provides a walkthrough of Lisp at the level of a college textbook. The book’s choice of Lisp dialect is Scheme.

The Little Schemer is another great introduction to Lisp using, you guessed it, Scheme.

I hope this series introduced you to the joys of functional programming. There’s a lot more that I didn’t discuss here, but the best way to familiarize yourself with functional programming is to use it a little bit each day, so put down the for-loop and reach for the map function.


This is the fourth post in a series on functional programming:

  1. What Is Functional Programming?
  2. Ideas & Patterns
  3. When & When Not to Use It
  4. Ideas for Practicing & Exploring