bsless / clj-fast

Unpredictably faster Clojure
Eclipse Public License 2.0
242 stars 1 forks source link

Extend assoc-in #26

Closed bsless closed 3 years ago

bsless commented 3 years ago

Extend inline/assoc-in's arity to be variadic

Input paths are collected and execution is pre-planned such that a minimal number of get-s and assoc-s are performed.

Based on suggestion by @yuhan0 at #23

yuhan0 commented 3 years ago

Looks great! I wonder if it's understood that these code transformations don't work predictably with side effects (luckily not a regular thing in Clojure)

(def counter (atom 0))

(assoc-in {}
  [(swap! counter inc) :a] "first"
  [(swap! counter inc) :b] "second")
;; => {2 {:a "first", :b "second"}}

(assoc-in {}
  [:x 1] (doto "first" println)
  [:y 2] (doto "second" println)
  [:x 3] (doto "third" println))

;; output:
first
third
second
bsless commented 3 years ago

There are no guarantees of order preservation or identification of "impure" keys. I should add a caveat in the doc string

yuhan0 commented 3 years ago

Yep, I don't know if any other macros here violate these guarantees, but perhaps it should be a library-wide caveat (Don't mix impurity with code-optimizing macros!)