Rich Hickey a écrit : > > On May 13, 9:57 am, Christophe Grand <christo...@cgrand.net> wrote: > >> Mark Reid a écrit : >> >> >>> In particular, it seems converting `(+ 1 2 3)` to `(+ 1 (+ >>> 2 3))` can speed things up. >>> >> Rich, would you accept a patch to make all arities inlinable for basic >> math ops? >> >> > > What does the patch do?
Here is the patch, it breaks tests in contrib for (-) and (/) since both forms now throw an exception at compile-time. -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 2f594af..6897e55 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -546,45 +546,46 @@ (reduce conj () coll)) ;;math stuff -(defn + +(defmacro + #^{:private true} def-left-op + [op docstring & bodies] + (let [macro-fn (clojure.lang.Compiler/eval + `(fn + ~...@bodies + ([x# y# & more#] `(~'~op (~'~op ~x# ~y#) ~...@more#)))) + has-zero? (reduce #(or %1 (= [] (first %2))) false bodies) + x (gensym "x") + y (gensym "y")] + `(defn ~(with-meta op {:inline macro-fn}) + ~docstring + ~@(when has-zero? `(([] ~(macro-fn)))) + ([~x] ~(macro-fn x)) + ([~x ~y] ~(macro-fn x y)) + ([x# y# & more#] (reduce ~op (~op x# y#) more#))))) + +(def-left-op + "Returns the sum of nums. (+) returns 0." - {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y))) - :inline-arities #{2}} ([] 0) - ([x] (cast Number x)) - ([x y] (. clojure.lang.Numbers (add x y))) - ([x y & more] - (reduce + (+ x y) more))) + ([x] `(cast Number ~x)) + ([x y] `(. clojure.lang.Numbers (add ~x ~y)))) -(defn * +(def-left-op * "Returns the product of nums. (*) returns 1." - {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y))) - :inline-arities #{2}} ([] 1) - ([x] (cast Number x)) - ([x y] (. clojure.lang.Numbers (multiply x y))) - ([x y & more] - (reduce * (* x y) more))) + ([x] `(cast Number ~x)) + ([x y] `(. clojure.lang.Numbers (multiply ~x ~y)))) -(defn / +(def-left-op / "If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators." - {:inline (fn [x y] `(. clojure.lang.Numbers (divide ~x ~y))) - :inline-arities #{2}} - ([x] (/ 1 x)) - ([x y] (. clojure.lang.Numbers (divide x y))) - ([x y & more] - (reduce / (/ x y) more))) + ([x] `(/ 1 ~x)) + ([x y] `(. clojure.lang.Numbers (divide ~x ~y)))) -(defn - +(def-left-op - "If no ys are supplied, returns the negation of x, else subtracts the ys from x and returns the result." - {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~...@args))) - :inline-arities #{1 2}} - ([x] (. clojure.lang.Numbers (minus x))) - ([x y] (. clojure.lang.Numbers (minus x y))) - ([x y & more] - (reduce - (- x y) more))) + ([x] `(. clojure.lang.Numbers (minus ~x))) + ([x y] `(. clojure.lang.Numbers (minus ~x ~y)))) (defn < "Returns non-nil if nums are in monotonically increasing order,