Week 6 Day 1 – Feeling my way in Clojure

So i am starting to learn a bit of Clojure. It’s not completely alien to me because i’ve done a little bit of SICP with Scheme, another variant of Lisp. The syntax seems quite logical to me, and i like its simplicity.

At the moment we seem to be running everything within the console rather than writing to a file. So i’ll just paste what i’m learning in here.

Lists, Maps, Sets and Vectors

This is quite a lot to take on board. Let me see if i can distill it.

Lists and vectors are ordered. Sets and maps are unordered but can be sorted with the sort and sort-map functions, respectively.

Use lists for code and vectors for data. Vectors are optimized for random access. Maps are key-value pairs. Sets and maps are magically also functions, which to me seems really bizarre but powerful!

Functions

We define data with def and a functions with defn. I didn’t know that you can add an optional string for documentation of a function. That’s nice. Parameters go as a vector, and then it’s the body of the function.

There is a cool trick with destructuring the parameters: if you’re passed more than you actually need, you can pull out just the bits that you want to work with. I see similarities from Scala and Erlang pattern matching.

First exercise

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

(defn big [st n] (> (count st) n))

defn defines a function, the name is ‘big’, there are two parameters and we check whether the length of the first is greater than the second.

Second exercise

Write a function called (collection-type col) that returns :list, :map, or :vector based on the type of collection col.

First i tried this just to see what would happen:

(defn collection-type [col] (type col))

Actually something quite interesting happens:

user=> (collection-type '(:r2d2 :c3po))
clojure.lang.PersistentList

user=> (collection-type [:hutt :wookie :ewok])
clojure.lang.PersistentVector

user=> (collection-type {:darth-vader "obi wan", :luke "yoda"})
clojure.lang.PersistentArrayMap

I thought about doing a grep for the last word starting with a capital letter, lowercasing it, prefixing it with a colon … that would have been neat but it would also require clojure-contrib (community created extensions) which i couldn’t find out how to include.

So i’m not going to do that.

Fortunately there are shortcut functions we can use:

(defn collection-type [col] (vector? col))

This will return true if the collection given is a vector. There are similar functions for list? and map? so we can use some kind of test to see what we get.

I wanted some kind of if function that could take multiple options followed by results. The Clojure answer to that is a cond function.

And here it is (updated to close all the parentheses on one line as suggested by Tom):

(defn collection-type [col]
  (cond
    (list? col) :list
    (vector? col) :vector
    (map? col) :map))

I can learn to love parentheses! :)

Advertisements

11 comments on “Week 6 Day 1 – Feeling my way in Clojure

  1. Just a tiny note on usual syntax. Standard lisp style puts all of the closing parens together, so your last function should look like this:

    (defn collection-type [col]
    (cond
    (list? col) :list
    (vector? col) :vector
    (map? col) :map))

    • yes, some kind of pattern matching has been a recurring theme in the book. as has higher order functions. it’s great to see the connections and differences.

  2. What languages do you currently use for work? I’m coming into Clojure from a pure empirical background, so concepts like having a function return a vector of vectors is still a struggle. The Google Clojure group is pretty friendly and have helped me get over hurdles.

    The only way I could learn Clojure was to design a small production project and implement it. That and a bug with embedded C code in Informix were incentive enough to start working more in Clojure.

    Good luck.

  3. Currently, I have three books, Programming Clojure, The Joy of Clojure, and Practical Clojure. This is a pretty high book count for me at this point ~2 mos in learning a new language — because usually one or two will get me through the learning stage. All three books present Clojure differently and interestingly, and in my opinion, all are well-written.

    However, these books and most on-line material I have read do not bridge the empirical OO and non-OO language and functional programming language mindsets. Programming Clojure goes a along way to provide some guidelines on Clojure programming in The Six Rules of Clojure FP. Those are good starting rules, but still I’ve found nothing that says, for example, here is how Clojure treats a function that returns a structure, list, pointer, and so on.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s