store/[org.clojure/clojure "1.8.0"] clj::clojure.core/doto

Official Documentation

Add notes
Arities
==================================================
   [x & forms]

Docstring
==================================================
  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))

Source

(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)))

Example 1

Edit
;; quick demonstration of using a Collections function on the resulting ArrayList

(def al (doto (java.util.ArrayList.) (.add 11) (.add 3) (.add 7)))
;; => #'user/al

al
;; => #<ArrayList [11, 3, 7]>

(java.util.Collections/sort al)
;; => nil

al
;; => #<ArrayList [3, 7, 11]>

Example 2

Edit
;; Note that even though println returns nil, doto still returns the HashMap object
(doto (java.util.HashMap.)
  (.put "a" 1)
  (.put "b" 2)
  (println))
;; > #<HashMap {b=2, a=1}>
;; => {"b" 2, "a" 1}

Example 3

Edit
;; Be careful when calling 'dotimes' from within a 'doto' statement
(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)

(macroexpand
 '(doto (java.util.ArrayList.)
    (.add -2)
    (.add -1)
    (dotimes [i 3] (.add i))))

;; => (let* [G__15339 (java.util.ArrayList.)]
;;      (.add G__15339 -2)
;;      (.add G__15339 -1)
;;      (dotimes G__15339 [i 3]
;;        (.add i)) G__15339)

;; 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'

(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

;; Another option is to wrap 'dotimes' in a function literal
(doto (java.util.ArrayList.)
  (.add -2)
  (.add -1)
  (#(dotimes [i 3] (.add % i))))
#<ArrayList [-2, -1, 0, 1, 2] >
;; exactly what we intended again

Uses on crossclj