Getting Started With Clojure


Prerequisites


  • JDK 6 or later
  • A text editor of your choice

What is clojure?

  • A functional programming language
  • Runs on JVM, CLR, and anywhere javascript runs
  • A Lisp

Clojure Tooling: Leiningen

  • Leiningen is support tooling to make clojure use easy.

  • OSX:
brew install leiningen
 
  • Ubuntu (apt has an ancient version, don't use apt)
wget http://goo.gl/05pplr
Then rename it to "lein" and add it to your path

  • Windows
http://leiningen-win-installer.djpowell.net/

Test Lein works

  • Type "lein" at the command line.

More Info on all things leiningen:
https://github.com/technomancy/leiningen/blob/master/README.md

FOLLOWING ALONG

  • It's better to learn by doing
  • However if you get behind and need to catch up, you can goto: 

https://github.com/philipsdoctor/clojure-installathon/


  • Each step should have it's own branch which I will indicate on the slide (ex: branch 'lein-new-project')

Leiningen : New Project

(branch 'lein-new-project')
New Project:                lein new app clojure-installathon
                                                 |         |        |             |
                                     {call lein}   |        |             |
                                    {new project}   |             |
                                         {template name}     |
                                                                    {the name of the project}
                                                

Brief Detour to the REPL

lein repl

clojure-installathon.core=> (+ 1 2)
3

LISP syntax, surround each function call with parenthesis.
Place the function first followed by parameters.
It returns the value and you can nest these:

clojure-installathon.core=> (+ (- 5 3) (* 2 3))
8

Define Some Stuff

clojure-installathon.core=> (def x 5)
#'clojure-installathon.core/x

clojure-installathon.core=> (println x)
5
nil

clojure-installathon.core=> (defn print-foo [foo] (println foo))
#'clojure-installathon.core/print-foo
clojure-installathon.core=> (print-foo 6)
6
nil

Try it

Define a function that takes two arguments and returns their sum.

All about Evaluation

  • No explicit return on functions
  • Take a look at if!


(if (> 1 2)
     "foo"
     "bar")

(prn  (if (> 1 2) "foo" "bar"))

First Look At APP code

Open ./src/clojure_installathon/core.clj

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

FIRST LOOK AT APP CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println ""Hello, World!""))

This is the namespace we are in, like java x.y.z means "src/x/y/z.clj'

FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println ""Hello, World!""))

This tells clojure to ahead-of-time compile, more on this towards the end

FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println ""Hello, World!""))
We're going to define a function in this namespace

FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println ""Hello, World!""))
Our function's name is "main" the '-' means static in java land.


FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println "Hello, World!"))
This is a docstring, it's a helpful documentation for a function

FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println "Hello, World!"))
These are function parameters, "&" is a special case accepting any number of parameters and storing them in a sequence called "args".  You'll often see parameters look like this [foo bar] which means two arguments are expected, foo and bar

FIRST LOOK AT CLOJURE CODE

(ns clojure-installathon.core
  (:gen-class))

(defn -main
  ""I don't do a whole lot ... yet.""
  [& args]
  (println ""Hello, World!""))

Calls the function 'println' with a string ''Hello, World!'' as the argument

Run a project with Leiningen

Run main defined in project:
lein run 

Run an arbitrary function:
lein run -m clojure-installathon.core/-main

Testing

(open ./test/clojure_installathon/core_test.clj)

(deftest a-test
  (testing "FIXME, I fail."
    (is (= 0 1))))

Run all tests:
lein test

Digging Deeper - 4clojure

http://www.4clojure.com/

Contains a number of challenges to help you learn more clojure.

Let's try some together

Higher Order Functions

(branch 'problem46-tests')
Functional Programming languages often have function that take another function as an input, or return a function as an output.

http://www.4clojure.com/problem/46 

Let's write failing tests, 4clojure provides them!

(solution on branch 'problem46-solution')

You try It

Try higher order functions yourself, goto:
http://www.4clojure.com/problem/107

Immutable Datastructures

Another clojure benefit is immutable datastructures.
  • When you modify data, you return a new values instead of changing the old value
  • Strings in many languages are already immutable, so you've probably seen this before
  • Think of it like numbers, you can never change the value of 2 by adding 1, instead you get a new value, 3!

http://www.4clojure.com/problem/56

You try It

http://www.4clojure.com/problem/33

Extra time?  Fix my sub-optimal use of (contains? (set...)...)

Add a Library

https://github.com/dakrone/cheshire
[cheshire "5.3.1"]

In project.clj
  :dependencies [[org.clojure/clojure "1.6.0"]
                                     [cheshire "5.3.1"]

How To Ship Clojure

  • Easy to package all dependencies and ship code:

lein uberjar

java -jar clojure-installathon-0.1.0-SNAPSHOT-standalone.jar 


Getting Started With Clojure

By Philip Doctor

Getting Started With Clojure

  • 2,311