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,

Reply via email to