Skip to content

Instantly share code, notes, and snippets.

@timsgardner
Last active August 29, 2015 14:08
Show Gist options
  • Save timsgardner/e760b62c8fc44c988cb3 to your computer and use it in GitHub Desktop.
Save timsgardner/e760b62c8fc44c988cb3 to your computer and use it in GitHub Desktop.
condcast-> example
(import '[UnityEngine Quaternion Vector3])
(set! *warn-on-reflection* true)
;; note this takes an optional default value. This macro is potentially
;; annoying in the case that you want to branch on a supertype, for
;; instance, but the cast would remove interface information. Use with
;; this in mind.
(defmacro condcast-> [expr xsym & clauses]
(let [exprsym (gensym "exprsym_")
[clauses default] (if (even? (count clauses))
[clauses nil]
[(butlast clauses)
[:else
`(let [~xsym ~exprsym]
~(last clauses))]])
cs (->> clauses
(partition 2)
(mapcat
(fn [[t then]]
`[(instance? ~t ~exprsym)
(let [~(with-meta xsym {:tag t}) ~exprsym]
~then)])))]
`(let [~exprsym ~expr]
~(cons 'cond
(concat cs default)))))
;; throws reflection warning:
(defn q* [^Quaternion q x]
(Quaternion/op_Multiply q x))
;; no reflection warning:
(defn q* [^Quaternion q x]
(condcast-> x x
Vector3 (Quaternion/op_Multiply q x)
Quaternion (Quaternion/op_Multiply q x)))
@timsgardner
Copy link
Author

stopgap for evading reflection with runtime type tests/casting until we develop something better (probably more of the same but with core.match)

@timsgardner
Copy link
Author

(defn q* [^Quaternion q x]
  (condcast-> x x
    Vector3    (Quaternion/op_Multiply q x)
    Quaternion (Quaternion/op_Multiply q x)))

is equivalent to

(defn q*  [^Quaternion q x]
  (let [exprsym_142 x]
    (cond
      (instance? Vector3 exprsym_142)
      (let [^Vector3 x exprsym_142]
        (Quaternion/op_Multiply q x))
      (instance? Quaternion exprsym_142)
      (let [^Quaternion x exprsym_142]
        (Quaternion/op_Multiply q x)))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment