Rich Hickey a écrit :
>
> On May 13, 9:57 am, Christophe Grand <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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,