|||

Rake Routes

by Stephen Ball

Clojure Functions in Four Ways

Perl may have coined TMTOWTDI (there’s more than one way to do it) but Clojure takes that idea and runs very far with it.

Today I’d like to quickly show you four ways to create a function in Clojure.

Each block of code will define a doubler function that simply doubles its given integer argument.

defn

This is essentially the standard way to define a function in Clojure: name, args, function body.

(defn doubler [n] (* 2 n))

def and fn

(def doubler (fn [n] (* 2 n)))

This is a verbose variant of defn and is essentially what defn is doing behind the scenes. Here we have an anonymous function (the fn bound to a name with def).

Function literals

Clojure also allows defining functions with an even shorter syntax than fn. The # character can define function literals. With that syntax you can’t have named arguments but instead get positional references e.g. %1 %2 %3

(def doubler #(* 2 %1))

Using partial

Now it gets interesting. Clojure provides the most wonderful and excellent partial function. The partial function accepts a function and some arguments and returns a new function that calls the original function with those originally given arguments plus any remaining required arguments.

Ah it’s hard to explain so I’ll show it: this is doubler using partial.

(def doubler (partial * 2))

What’s happening there?

The def doubler is simply assigning the name so let’s ignore that.

The real interesting bit

(partial * 2)

That call to partial accepts a function * and an argument 2 and returns a new function that will accept more arguments to supply to the (* 2) call.

The new function takes any arguments it’s given and supplies them to (* 2) as though we had called it directly.

(def doubler (partial * 2))

(doubler 10)  ; => 20 == (* 2 10)
(doubler 3 4) ; => 24 == (* 2 3 4)

You can see it’s not quite the same as the first two doubler functions in that it takes any number of arguments. Such is the power and flexibility of partial.

Up next See Some Clojure The Problem of State Among all the problems we create for ourselves when programming systems state is perhaps the most troublesome to deal with. Decisions made about the
Latest posts Where did the recent Elixir posts go? A subtle Go bug that types cannot help with swapcase with the tr command nice go test output See where vim settings came from Containers in the real world and backpressure in distributed systems Elixir Phoenix and “role postgres does not exist” From awk to a Dockerized Ruby Script Finding leap years with the cal command The Problem of State Clojure Functions in Four Ways See Some Clojure A simple language spec isn’t a feature when you’re building applications The Fastest Possible Tests Shrink your data into bitfields (and out again) Every “if” statement is an object waiting to be extracted Choose Generic Tools Hyperlinks you might find interesting — #4 Running bundle install on rails master Use tldr for command line examples Friday Lunch Links — #3 Friday Lunch Links — #2 Logical Solver: Turn facts into conclusions Programming with jq Command line tools - jq Friday Lunch Links — #1 Why diversity matters Music for coding - October 2019 Code puzzles are a poor way to gauge technical candidates Add vim to a pipeline with vipe Connecting Objects with Observable