Skip to content

Instantly share code, notes, and snippets.

@alandipert
Last active July 10, 2020 05:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alandipert/bb0f2d9d1212870534315707c929c191 to your computer and use it in GitHub Desktop.
Save alandipert/bb0f2d9d1212870534315707c929c191 to your computer and use it in GitHub Desktop.
(def mv-limit 20)
(def ^:dynamic *mv-arr*)
(def ^:dynamic *values-expected* 1)
(defn values [& vals]
(when (thread-bound? #'*values-expected*)
(dotimes [i (set! *values-expected*
(min *values-expected* (count vals)))]
(aset *mv-arr* i (nth vals i))))
(first vals))
(defn make-mv-bindings [bindings val1#]
(->> (iterate inc 1)
(take (count bindings))
(map (fn [i]
`(when (< ~i *values-expected* mv-limit)
(aget *mv-arr* ~i))))
(cons val1#)
(interleave bindings)))
(defmacro mv-bind [bindings expr & body]
(let [val1# (gensym)]
`(binding [*mv-arr* (if (thread-bound? #'*mv-arr*)
*mv-arr*
(make-array Object mv-limit))
*values-expected* ~(count bindings)]
(let [~val1# ~expr
~@(make-mv-bindings bindings val1#)]
~@body))))
(defn polar [x y]
[(Math/sqrt (+ (* x x) (* y y))) (Math/atan (/ y x))])
(defn polar-mv [x y]
(values (Math/sqrt (+ (* x x) (* y y))) (Math/atan (/ y x))))
(time
(dotimes [i 1e5]
(let [[r theta] (polar 3 4)])))
;; "Elapsed time: 70.3533 msecs"
(time
(dotimes [i 1e5]
(mv-bind [r theta] (polar-mv 3 4))))
;; "Elapsed time: 5894.5376 msecs"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment