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:
- 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'
(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
(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
(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.
(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
(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
(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
(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:
java -jar clojure-installathon-0.1.0-SNAPSHOT-standalone.jar
Getting Started With Clojure
By Philip Doctor
Getting Started With Clojure
- 2,304