Venice, like any other lisp dialect, does not have any explicit flow control operators as imperative languages do. Everything in Venice is an expression and returns a value.
do blocks sequentially execute multiple expressions. The value
of the last expression is returned.
(do (println "1000")
(println "2000")
20)
; => 20if takes three expressions, a condition, a "then", and an "else"
expression. The "else" expression is optional:
(str "2 is " (if (number? 2) "a number" "not a number"))
; => "2 is a number"
(if (pos? 100) "positive")
; => "positive"
(if (pos? -100) "positive")
; => nilTo handle larger blocks with multiple expressions presumable for
side effects use do
(if (number? 5)
(do (println "5 is number")
true)
(do (println "5 is not a number")
false))
; => falsewhen is an if with only a then branch. It checks a condition and
then evaluates any number of statements as a body in an implicit do.
The value of the last expression is returned. If the condition is
false, nil is returned.
(let [x 6]
(when (pos? x)
(println x "is positive")
x))cond is a series of tests and expressions with an optional else part.
Each test is evaluated in order and the expression is evaluated and
returned for the first true test.
(do
(defn test [x]
(cond
(> x 0) "x is positive"
(< x 0) "x is negative"))
(test 10) ; => "x is positive"
(test -10) ; => "x is negative"
(test 0) ; => nil
)with an else part:
(do
(defn test [x]
(cond
(> x 0) "x is positive"
(< x 0) "x is negative"
:else "x is zero"))
(test 10) ; => "x is positive"
(test -10) ; => "x is negative"
(test 0) ; => "x is zero
)case takes an expression and a list of clauses. Each clause takes the
form of a test constant and a result expression.
(do
(defn test [x]
(case (* x 10)
10 :ten
20 :twenty
30 :thirty))
(test 1) ; => :ten
(test 2) ; => :twenty
(test 3) ; => :thirty
(test 4) ; => nil
) with a default:
(do
(defn test [x]
(case (* x 10)
10 :ten
20 :twenty
30 :thirty
:dont-know))
(test 1) ; => :ten
(test 2) ; => :twenty
(test 3) ; => :thirty
(test 4) ; => :dont-know
) (for seq-exprs & body-expr)
For list comprehensions take a vector of one or more binding-form or collection-expr pairs,
each followed by zero or more modifiers (:when, :while, :let), and yields a collection of evaluations of the body expr.
(for [x (range 5)] x)
;; => [0 1 2 3 4](for [x (range 10) :when (odd? x)] (* x 2))
;; => [2 6 10 14 18](for [x (range 10) :when (odd? x) :let [p (* x 2)]] [x p])
;; => [[1 2] [3 6] [5 10] [7 14] [9 18]](for [x [1 2 3] :when (odd? x) y [1 2 3 4] :when (even? y)] [x y])
;; => [[1 2] [1 4] [3 2] [3 4]](for [x (range 10) :while (< x 4) y (range 6) :while (< y 6) :when (even? y)] [x y])
;; => [[0 0] [0 2] [0 4] [1 0] [1 2] [1 4] [2 0] [2 2] [2 4] [3 0] [3 2] [3 4]](dotimes binding & body)
dotimes repeatedly executes a body with a name bound to integers from 0 through n-1.
Returns nil.
(dotimes [n 3] (println "n is" n))
; "n is 0"
; "n is 1"
; "n is 2"
; => nil(doseq seq-exprs & body)
doseq repeatedly executes body (presumably for side-effects) with bindings and filtering
as provided by "list-comp". Does not retain the head of the sequence. Returns nil.
(doseq [x (range 10)] (print x))
;; 0123456789
;; => nil(doseq [x (seq "abc") y [0 1 2]] (print (pr-str [x y])))
;; ["a" 0]["a" 1]["b" 0]["b" 1]["c" 0]["c" 1]
;; => nil(doseq [x (range 10) :when (odd? x)] (print (* x 2) " "))
;; 2 6 10 14 18
;; => nil(docoll f coll)
Applies f to the items of the collection presumably for side effects. Returns nil.
(docoll #(println %) [1 2 3])
; 1
; 2
; 3
; => nil