Evaluates x then calls all of the methods and functions with the
value of x supplied at the front of the given arguments. The forms
are evaluated in order. Returns x.
(doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2))
;; Note that even though println returns nil, doto still returns the date object
user> (doto (java.util.HashMap.)
(.put "a" 1)
(.put "b" 2)
(println :printed))
#<HashMap {b=2, a=1}> :printed
#<HashMap {b=2, a=1}>
;; quick demonstration of using a Collections function on the resulting ArrayList user=> (def al (doto (java.util.ArrayList.) (.add 11) (.add 3)(.add 7))) #'user/al user=> al #<ArrayList [11, 3, 7]> user=> (java.util.Collections/sort al) nil user=> al #<ArrayList [3, 7, 11]> user=>
;; careful when calling 'dotimes' from within a 'doto' statement
user=> (doto (java.util.ArrayList.)
(.add -2)
(.add -1)
(dotimes [i 3] (.add i)))
java.lang.IllegalArgumentException: dotimes requires a vector for its binding (NO_SOURCE_FILE:1)
; what has happened is that (java.util.ArrayList.) has secretly become the first argument to 'dotimes' and thus the exception informs us that it can't find the binding vector required for 'dotimes' to expand. You can cure this behaviour by simply using 'do' instead of 'doto' or by wrapping the call to 'dotimes' in a function. e.g:
;using 'let' with implicit 'do' instead of 'doto'
user=> (let [al (java.util.ArrayList.)]
(.add al -2)
(.add al -1)
(dotimes [i 3] (.add al i))
al);return the ArrayList
#<ArrayList [-2, -1, 0, 1, 2]> ;exactly what we intended
;wrapping 'dotimes' in a function literal
user=>(doto (java.util.ArrayList.)
(.add -2)
(.add -1)
(#(dotimes [i 3] (.add % i))))
#<ArrayList [-2, -1, 0, 1, 2]> ;exactly what we intended again
(defmacro doto
"Evaluates x then calls all of the methods and functions with the
value of x supplied at the front of the given arguments. The forms
are evaluated in order. Returns x.
(doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"
{:added "1.0"}
[x & forms]
(let [gx (gensym)]
`(let [~gx ~x]
~@(map (fn [f]
(if (seq? f)
`(~(first f) ~gx ~@(next f))
`(~f ~gx)))
forms)
~gx)))
Comments top
No comments for doto. Log in to add a comment.