Clojure is an excellent language for learning Functional Programming. The following courses will guide you through the ideas you’ll need to master Functional Programming. Be sure to click those checkmarks to track your progress.
Calculations
Calculations are one of the three domains of Functional Programming. They are anything that transform input values to output values. Their results are not dependent on when you run them or how many times you run them. In Clojure, we build calculations from pure functions. Because pure functions don’t depend on time, we can test them whenever we want and as many times as we want. Contrast this to testing sending an email (an Action)–certainly sending a million emails is different from sending one. And so we are very limited in how we test an Action.
Higher-order functions are very important in Functional Programming. They are functions that take functions as an argument. These courses will teach you about the three most common ones: map, filter, and reduce.
Recursion is an important topic in Functional Programming. And though you may not use it in all functions, it is the main way to write loops in functional languages.
Combinators are functions that return other functions. They are typically considered advanced material, but each combinator is not hard to learn on its own. This course goes through several, showing how each is implemented.
Data
Data is another of the three domains of Functional Programming. Data, by itself, is inert and self-identical (it is what it is). It requires interpretation. For instance, 3kg is a piece of data, but what does it mean? Is it how many tomatoes I want to buy? Or is it the mass of backpack? We use data to represent facts about events in the world.
Clojure uses its immutable collections library extensively. In this course, we dive into the collections, their properties, and idiomatic patterns for using them.
Clojure’s sequences are lazy, which is powerful, but it has some drawbacks. This course helps you understand the tradeoffs and how to use laziness to your advantage without getting caught.
This course shows how we can use Data to model interesting properties of our systems.
Actions
Actions are the third domain in Functional Programming. They represent things that change the world, and are hence bound up in time. They depend on when they are run or how many times they are run. Interestingly, Functional Programming has a lot to say about Actions, probably more than other paradigms that use Actions more.
Clojure’s concurrency primitives are all ways of managing Actions. They are means of safely sharing resources, like mutable state, without getting into a mess.
Clojure’s core.async library provides another, more sophisticated concurrency primitive that lets us program complex message-passing scenarios with intricate timings.
Language Features
There are some language features that help us program more functionally.
Scoping rules help us manage Data stored in variables. The rules tell us what code has access to which variables.
Protocols are an interesting hybrid approach to polymorphism. If you’re used to Object-Oriented Programming, polymorphism is very common. Clojure has type-based polymorphism as well. By using Protocols, we can define common behavior for any Java types, whether they are new or pre-existing.
Destructuring is a shortcut for assigning values in collections to local variables. It’s often used because we commonly use a lot of collections.