June 28, 2018

Practical Functional Programming: Prelude

This series is a practical guide to applying techniques from functional programming (FP) to:

  • Avoid common errors
  • Translate your designs into code using types
  • Construct software that can evolve

tl;dr

Want to jump straight in? These posts have been published so far:

You

Are you a web developer using JavaScript—maybe even TypeScript or Flow—and feel like you still too often run into problems with…

  • …unexpected runtime errors?
  • …gnarly parts of code that become harder to maintain over time?
  • …new features breaking existing parts of your app?

Or: Have you grasped the basics of functional programming and are wondering how to apply that knowledge in real-world situations?

If you’ve answered yes to any of these, keep on reading.

Me

I am a developer with 10 years of experience writing software professionally and 20 years of doing it for fun.

In all those years, I’ve used many different programming languages. Out of all of them, functional programming languages broadened my perspective the most. Learning and using them made me a more skilled and confident developer.

Journey

It was the Saturday after Thanksgiving in 2015. Ahead of me was a 31 hour train ride back home, from Santa Barbara, CA, to Seattle, WA, on the Coast Starlight. Once comfortable in my seat, I decided it was time to finally learn Haskell and discover what FP is all about. I’ve attempted it twice before: First in 2008 when I was originally introduced to Haskell in my Formal Methods and Functional Programming class at ETH. The second time was in 2009, when I tried to write a DeepZoom image tiler in Haskell. On neither occasion did it click for me. But I knew this time it would!

What did I do differently? I picked a project that was both real, unlike toy problems I’ve attempted in the past, and one I understood well — two big boosts for my motivation. My choice: ZoomHub, a side project that a few friends from Microsoft and I started.

ZoomHub is a place to share and view high-resolution images. It provides a small REST API for developers to publish their own images. We wrote it in CoffeeScript on top of Node.js, a stack we were familiar with from our day jobs. After a while, life got in the way and my friends’ priorities changed. I still wanted to see the project through but it was hard to invest large chunks of my free time because I didn’t learn anything new technically. This is what made the project a suitable starting ground for learning Haskell.

What began on the train with a port of the REST API from Node.js to Haskell, using the novel servant library, reached its first milestone just a few months later when in April, 2016, I shipped the Haskell implementation of ZoomHub to production. Today, ZoomHub serves thousands of page views a month and I can sleep soundly as it rarely has any issues.

Motivation

Learning functional programming has been a very rewarding journey. But I’d lie if I didn’t mention that the road was paved with frustration and late nights deciphering dense error messages. What kept me going was a strong belief that there must a more sustainable and enjoyable way to write large programs than imperative and object-oriented languages offered. While not a silver bullet by any means, I found a lot of good in functional programming.

But if all you know is that FP languages have weird syntax and use intimidating math terms, you might ask yourself: What’s the point of leaving behind what I’m comfortable with and going through the struggle of learning this new way of doing things? That’s what this series is about. Presenting short, but realistic, examples of the benefits you gain by adopting FP and types.

We’ll learn why the combination of features such as immutability, algebraic data types (ADT), value types, purity and effects, etc. results in a whole that is greater than the sum of its parts. I will show how each one can be used to solve a particular problem we have in modern web development using JavaScript.

Beginners can find many valuable resources about the basics of FP and learning a particular language. Likewise, for experts, there are many discussions about advanced topics such as monad transformers, type-level programming, and category theory. However, they can be intimidating and, more importantly, distracting for someone new to FP as they are—based on personal experience—not required to build useful applications.

This observation is touched upon in The Haskell Pyramid: Learning enough Haskell to be productive takes far less effort than people imagine. Though if you follow Haskell experts on social media, it seems daunting to even begin the journey.

Wanting to become productive myself, I struggled to find good articles about intermediate level topics on types and functional programming and how they can be effectively applied in real-world situations. This reminds me of when I first learned OOP. Most examples were about Ball and Ball::bounce(), or Animal, Dog, Cat, and Animal::sayHello(), whereas I was looking to figure out how OOP could help me separate my data fetching from my presentation logic.

My goal for this series is to bridge that gap and show that it doesn’t take much to become productive with functional programming and using types as a tool to build more robust applications.

So far, I’ve shared my passion for functional programming and type-driven development with my past three teams:

  • FiftyThree: Functional Programming for Fun & Profit
  • Shutterstock: Type-Driven Development. Internally presented a case study about six bugs we’ve encountered in production and how using a functional programming language and types could have prevented them and made our app more maintainable.
  • Signal: Implemented proof of concept for integrating PureScript with Signal Desktop. It demonstrates how explicitly defining your domain types, e.g. Conversation, Message, Attachment, etc., can help you better understand your app’s behavior and how to safely extend it.

Practical Functional Programming is about sharing what I learned more broadly.

Structure

Each post in this series will consist of a description of a Problem, an Example, a Cause where helpful, and then a Solution to the problem using techniques from functional programming. Finally, we’ll wrap it up with a Conclusion.

All posts aim to stand on their own, meaning you can jump between the various parts of the series based on your interest.

Code

To make it more approachable for web developers, I will write examples in PureScript and compare them to JavaScript or TypeScript, to make the connection to something you may already be familiar with.

PureScript is a purely functional, strongly-typed language that compiles to JavaScript. Having the benefit of being newer, PureScript addresses some of the idiosyncrasies of Haskell. Not only can it be compiled to JavaScript, it also plays nicely with existing JavaScript. This makes it an exceptional tool for web developers to build large and reliable applications.

Next Steps

Dive into Part One: Practical Functional Programming: The Billion Dollar Mistake.

Optional: If you want to actively follow along, set up your environment by following the Getting Started with PureScript instructions. Learn the basics of the language by reading the excellent PureScript by Example by Phil Freeman, its creator.


Thanks to Aseem, Boris, Gerd, Matt, Shaniece, and Stephanie for reading drafts of this.


Resources