Clojure is a programming language.
A Modern Lisp
Brief History of Lisp
11+ currently maintained Lisp dialects
Lisp Overview
Lisp Syntax
(defun square (x)
(* x x))
(square (5)) ; => 25
(+ (* 2 3) 1) ; => 7
REPL
Lisp primitive functions
LISt Processing
(setq list '(1 2 3))
(defun sum (list)
(if (null list) ;; conditional like JS ternary operator!
0
(+ (first list)
(sum (rest list))))) ; => 6
Everything's a list (s-expressions)
Macros
Meta programming
(defmacro inc (x)
(list 'setq x (list '1+ x)))
(inc 5) ; expands to (setq 5 (1+ 5))
; evals to => 6
Lisp in the real world
Back to Clojure
Syntax
(defn hello [] ;; Minor differences from CL, notice defn instead of defun
"Hello World!"
) ;; Args use square brackets
(hello) ;=> "Hello World!"
(+ (* 2 3) 1) ;=> still 7
Targets JVM and JavaScript
Immutable
Functional
Concurrent
Demo
$ lein new luminus lumi-demo +cljs +h2 // generate project with database and clojurescript
$ cd lumi-demo
$
$ lein run // start app
// Poke through the code while server starts up, go to localhost:3000
$ git clone git@github.com:luminus-framework/guestbook.git
$ cd guestbook
$ lein ragtime migrate // migrate database
$ lein run
// Again visit localhost:3000, show off database workings
Demo
$ lein new overtone-demo
$ cd overtone-demo
$ emacs
;; add [overtone "0.9.1"] to :dependencies in project.clj
$ lein deps
;; cider-jack-in or $ lein repl
Demo
;; overtone-demo/core.clj
(ns overtone-demo.core
(:use
[overtone.live :refer :all])
(def hihat (sample (freesound-path 250530)))
(def kick (sample (freesound-path 2086)))
(def snare (sample (freesound-path 212208)))
(defonce met (metronome 180))
(defn drum-loop [m beat]
(at (m (+ 0 beat)) (kick) (hihat))
(at (m (+ 0.5 beat)) (hihat))
(at (m (+ 1 beat)) (snare) (hihat))
(at (m (+ 1.5 beat)) (hihat))
(at (m (+ 2 beat)) (kick) (hihat))
(at (m (+ 2.5 beat)) (hihat))
(at (m (+ 3 beat)) (snare) (hihat))
(apply-at (m (+ 4 beat)) drum-loop m (+ 4 beat) [])
)
(drum-loop met (met))
Demo
$ lein new quil-demo
$ cd quil-demo
$ emacs
;; add [quil "2.2.5"] to :dependencies in project.clj
$ lein deps
;; cider-jack-in or $ lein repl
Demo
;; quil-demo/core.clj
(ns quil-demo.core
(:require [quil.core :as q]))
(defn setup []
(q/smooth)
(q/frame-rate 30))
(defn draw []
(q/stroke (q/random 255) (q/random 255) (q/random 255))
(q/stroke-weight (q/random 50))
(q/fill (q/random 255) (q/random 255) (q/random 255))
(let [diam (q/random 180)
x (q/random (q/width))
y (q/random (q/height))]
(q/ellipse x y diam diam)))
(q/defsketch demo
:title "Random colorful circles"
:setup setup
:draw draw
:size [1292 800])
Overtone + Quil
Demo
$ lein new quilover-demo
$ cd quilover-demo
$ emacs
;; add [quil "2.2.5"] and [overtone "0.9.1"] to :dependencies in project.clj
$ lein deps
;; cider-jack-in or $ lein repl
Overtone + Quil
Demo
;; quilover-demo/core.clj
(ns quilover-demo.core
(:require [quil.core :as q]
[overtone.live]))
(defn setup []
(q/smooth)
(q/stroke-weight (q/random 50))
(q/fill 150 50)
(q/set-state! :mouse-position (atom [0 0])))
(def boing (sample (freesound-path 140867)))
(defn draw-circles []
(dorun
(for [i (range 0 300)]
(let [x (q/random (q/width))
y (q/random (q/height))
radius (+ (q/random 100) 60)]
(q/ellipse x y (* 2 radius) (* 2 radius))
(q/stroke (q/random 255) (q/random 255) (q/random 255))
(q/fill (q/random 255) (q/random 255) (q/random 255))
(q/ellipse x y (q/random 500) (q/random 500))))))
(defn capture-click []
(let [[x y] @(q/state :mouse-position)]
(boing)
(draw-circles)))
(q/defsketch gen-art-30
:title "Click Boing Shapes"
:setup setup
:mouse-pressed capture-click
:size [900 600])
Other Sources