recur

special formsince v0.0-927 clojure.core/recurEdit
(recur exprs*)

Source docstring:
Evaluates the exprs in order, then, in parallel, rebinds
the bindings of the recursion point to the values of the exprs.
Execution then jumps back to the recursion point, a loop or fn method.
Parser code @ clojurescript:src/main/clojure/cljs/analyzer.cljc
(defmethod parse 'recur
  [op env [_ & exprs :as form] _ _]
  (let [context (:context env)
        frame (first *recur-frames*)
        ;; Add dummy implicit target object if recuring to proto impl method head
        add-implicit-target-object? (and (:protocol-impl frame)
                                         (= (count exprs) (dec (count (:params frame)))))
        exprs (cond->> exprs add-implicit-target-object? (cons nil))
        exprs (disallowing-recur (vec (map #(analyze (assoc env :context :expr) %) exprs)))]
    (when-not frame
      (throw (error env "Can't recur here")))
    (when-not (= (count exprs) (count (:params frame)))
      (throw (error env (str "recur argument count mismatch, expected: "
                          (count (:params frame)) " args, got: " (count exprs)))))
    (when (and (:protocol-impl frame)
               (not add-implicit-target-object?))
      (warning :protocol-impl-recur-with-target env {:form (:form (first exprs))}))
    (reset! (:flag frame) true)
    (swap! (:tags frame) (fn [tags]
                           (mapv (fn [tag expr]
                                   ;; Widen by adding the type of the recur expression, except when recurring with a
                                   ;; loop local: Since its final widened type is unknown, conservatively assume 'any.
                                   (if (= :loop (:local expr))
                                     'any
                                     (add-types tag (:tag expr))))
                             tags exprs)))
    (assoc {:env env :op :recur :form form}
      :frame frame
      :exprs exprs
      :children [:exprs])))

Emitting code @ clojurescript:src/main/clojure/cljs/compiler.cljc
(defmethod emit* :recur
  [{:keys [frame exprs env]}]
  (let [temps (vec (take (count exprs) (repeatedly gensym)))
        params (:params frame)]
    (dotimes [i (count exprs)]
      (emitln "var " (temps i) " = " (exprs i) ";"))
    (dotimes [i (count exprs)]
      (emitln (munge (params i)) " = " (temps i) ";"))
    (emitln "continue;")))