I explore data, write algorithms, and build systems.
A few of my favorite things: statistics, machine learning, complexity theory, information theory, and social complexity.
by Matt Revelle
Earlier today on #clojure, there was a brief discussion on how larger (including infinite!) arity functions are implemented in Clojure. An example similar to what started the discussion:
(apply + (range 100))
(defn +
"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)))
So far we have:
(apply f xs) -> f.applyTo(xs).
This then calls:
f.doInvoke(xs.first(), (xs = xs.next()).first(), xs.next())
Which matches the implementation that handles the parameter list [x y & more]. The Clojure compiler, when emitting the bytecode for +, places the implementation defined for [x y & more] under the appropriate doInvoke method and overrides RestFn's default implementation of throwing an exception about an unsupported arity.
Comments 0 Comments