I attached a better patch: no eval and a more standard "inline".

Christophe Grand a écrit :
> I'm sure there's something wrong with my patch (the "eval" smell) and 
> the fact that I'm assoc-ing a closure in the metadat map.
> I'll rework it if you agree with the idea of this patch
>
> Christophe Grand a écrit :
>   
>> 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..41f79e1 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -546,45 +546,43 @@
     (reduce conj () coll))
 
 ;;math stuff
-(defn +
+(defmacro
+ #^{:private true} def-left-op
+ ([op docstring unary binary] `(def-left-op ~op ~docstring false nil ~unary ~binary)) 
+ ([op docstring zero unary binary] `(def-left-op ~op ~docstring true ~zero ~unary ~binary)) 
+ ([op docstring has-zero? zero unary binary] 
+  (let [inlines (list
+                  `([x#] (concat '~unary [x#]))  
+                  `([x# y#] (concat '~binary [x# y#]))
+                  `([x# y# & more#] (reduce (fn [& xy#] (concat '~binary xy#)) (list* x# y# more#))))
+        inlines (if has-zero? (cons `([] ~zero) inlines) inlines)
+        arities (list  
+                  `([x#] (~...@unary x#))
+                  `([x# y#] (~...@binary x# y#))
+                  `([x# y# & more#] (reduce ~op (~op x# y#) more#)))
+        arities (if has-zero? (cons `([] ~zero) arities) arities)]
+   `(defn ~op
+      ~docstring
+      {:inline (fn ~...@inlines)}
+      ~...@arities))))
+
+(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)))
+  0 (cast Number) (clojure.lang.Numbers/add))
 
-(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)))
+  1 (cast Number) (clojure.lang.Numbers/multiply))
 
-(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)))
+  (/ 1) (clojure.lang.Numbers/divide))
 
-(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)))
+  (clojure.lang.Numbers/minus) (clojure.lang.Numbers/minus))
 
 (defn <
   "Returns non-nil if nums are in monotonically increasing order,

Reply via email to