Clojure Day 1

My experience with day one of exploring Clojure through Seven Languages in Seven Weeks.

Clojure is a language I’ve been meaning to get around to looking at for a while so I guess now’s my chance. It is another language that runs on the JVM like Scala and is based on Lisp. Running on the JVM means it has access to all the Java libraries. This means you’ll often find a library which does what you need instead of having to implement everything form scratch. It is another functional language and is dynamically typed.

After Fortran, Lisp is the oldest commercially active language. The acronym stands for LISt Processing and it is a language of lists. A function call uses the first list element as the function and the rest as the arguments more on this later but it takes a while to get your head around the syntax after years of infix notation. It’s a very flexible language ideal for metaprogramming.

Although Clojure is a relatively new language it has a strong community which is good news for me as it makes learning it a whole lot easier!

Full instructions on how to get set up are included on the Clojure site. In the book Tate uses Leiningen tool2, a Clojure build tool to simplify his builds. It is a popular tool and there are a range of plugins for it which the community have created and are available via github. I see there is also a Clojure Maven Plugin which I’ll have to take a look at sometime having used Maven for most of my recent Java projects. Simple code can be tested in Clojure’s console called REPL. For more complex tasks you’ll need an IDE with Clojure support. Netbeans, VIM, Eclipse and emacs all provide suitable IDEs.

Full instructions on how to get set up are included on the Clojure site. In the book Tate uses Leiningen tool2, a Clojure build tool to simplify his builds. It is a popular tool and there are a range of plugins for it which the community have created and are available via github. I see there is also a Clojure Maven Plugin which I’ll have to take a look at sometime having used Maven for most of my recent Java projects. Simple code can be tested in Clojure’s console called REPL. For more complex tasks you’ll need an IDE with Clojure support. Netbeans, VIM, Eclipse and emacs all provide suitable IDEs.

Calling Basic Functions

The first thing to get your head around in Clojure is the prefix notation. A function call is enclosed entirely in parenthesis, with the first element being the function name and the rest the arguments.

A nice addition for division is the ratio data type. This allows you to delay computation to avoid loss of precision

Surrounding each function call in parenthesis has the advantage of making it very clear what arguments belong to what call. Clojure evaluates the functions in parenthetical order.

You can achieve some neat things with minimal syntax. In the example below I’m checking if the list of arguments is in ascending order.

Here’s a string example. The str function calls the underlying Java toString function to concantenate strings togethers.

Here’s how you code an if else. The first parenthesis is the condition to test, the second the code to be carried out if it is true and the third the code to be carried out if it is false.

Lists, Maps, Sets and Vectors

Lists

As lists evaluate to functions you can’t do (1 2 3) as this will generate an error instead you need to do one of the following.

Clojure provides functions to allow you to manipulate the list. Here are some examples below.

Vector

Here is how you define a vector.

Here are some examples of functions you can use to manipulate a list.

Note in the last example Clojure is returning a sequence and rendering it as a list rather than a vector in the repl.

Sets

You define a set using the #{} syntax.

We can assign the set to a variable called animals and then manipulate them.

Here are some examples of how we can manipulate a set using functions provided by Clojure.

It is possible to create a sorted set that takes items in any order and returns them in sorted order.

Maps

You represent a map with curly braces

In the example below we can see that maps and keywords are functions so :ireland as a function looks itself up in map.

You can create a sorted map that takes items in any order and returns them sorted.

Functions

Here is an example of how to define a function. We use the keyword defn to define it. The first String describes the function. This can be displayed using (doc force-it). We then have a parameter list. In this case there is one parameter, jedi. Finally we have the function body which simply concantenates the parameter to a string.

Bindings

Binding is the process of assigning parameters based on inbound arguments. Clojure provides a concept called destructuring which allows you to access any part of a parameter as an argument. Destructuring is a form of pattern matching. In the example below, board represents a noughts and crosses board. If we want to select the second element of the second list i.e. the centre value we could use the following code. Really nice and powerful syntax.

We’re ignoring the first and third elements, which are the top and bottom rows in our board. We then select the second element of the middle row. This can be further simplified to the following as we don’t care about what follows the value we’re selecting.

You can use destructuring in a let statement as well as an argument list .let binds a variable to a value. We could use let to hide the destructuring from the clients of the center function. Both forms produce equivalent results. It all depends on where you want the destructuring to happen.

You can destructure a map.

Anonymous Functions

Clojure allows the creation of anonymous functions using the fn function.

Map in the example below is a higher-order function as it takes a function count as input. It generates a list of the length of people’s names.

The example below uses an anonymous function to build a list of double the length of people’s names.

This can be shortened to the following where # defines an anonymous function, with % bound to each item of the sequence.

Higher order functions

apply applies a function to an argument list.

The filter function takes a function that is a test and returns the sequence of elements that pass the test.

Conclusion

At the end of the chapter is an interview with Rich Hickey, Creator of Clojure. What comes across is how he designed Clojure with a particular purpose in mind having identified a gap in the market for a predominantly functional,extensible, dynamic language, with solid concurrency features for the JVM and CLR. Unlike previous Lisp dialects Clojure is aimed as a general purpose production programming and unlike previous dialects is written with an understanding that most development is done in teams.(Other dialects aim to enpower the individual but encourage code which doesn’t work well in a team environment)

Find:

Examples using Clojure sequences

http://clojure.org/sequences

http://www.gettingclojure.com/cookbook:sequences

blip.tv/clojure/clojure-sequences-740581

The formal definition of a Clojure function

http://clojure.org/functional_programming

A script for quickly invoking the repl (clojure console) in your environment

http://en.wikibooks.org/wiki/Learning_Clojure/Installation#Windows_Configuration

Do:

Implement a function called (big st n) that returns true if a string st is longer than n characters.

Write a function called (collection-type col)