There is literal data:
; number
1.23
; string
"foo"
; keyword (like strings, but used as map keys)
:foo
; vector (array)
[:bar 3.14 "hello"]
; map (associative array)
{:msg "hello" :pi 3.14 :primes [2 3 5 7 11 13]}
; set (distinct elements)
#{:bar 3.14 "hello"}And there is symbolic data:
; symbol (represents a named value)
foo
; list (represents a "call")
(foo :bar 3.14)Clojure can evaluate data to create a new "value" from it.
-
Literal data evaluates to itself, of course:
1.23 ; => 1.23 "foo" ; => "foo" [:bar 3.14 "hello"] ; => [:bar 3.14 "hello"]
-
A symbol evaluates to the value bound to it:
foo ; => 3 -
A list evaluates to the return value of a "call".
(+ 1 2 3) ; => 6 (= 1 2) ; => false (if true "y" "n") ; => "y"
That's all the syntax. Core functions fill in the rest:
;; create a var
(def a 1)
;; create a function
(defn foo [a b] (+ a b))
;; for loop - generates even numbers
(for [x (range)] (* x 2))
;; for loop - side effects
(doseq [x [1 2 3]] (println x))
;; if statement
(if (= a 1)
(println "a is 1")
(println "a isnt 1"))
;; if expression - like a ternary
(if (= a 1) "a is 1" "a isnt 1")