Seperate so it can be easily ignored:
Changed in core.clj:
(defn nth
"Returns the value at the index. get returns nil if index out of
bounds, nth throws an exception unless not-found is supplied. nth
also works for strings, Java arrays, regex Matchers and Lists, and,
in O(n) time, for sequences."
{:inline (fn ([c i] `(. clojure.lang.RT (nth ~c ~i)))
([c i n] `(. clojure.lang.RT (nth ~c ~i ~n))))
:inline-arities #{2 3}}
([coll index] (. clojure.lang.RT (nth coll index)))
([coll index not-found] (. clojure.lang.RT (nth coll index not-
found))))
;;changed to inline the 3ary version of nth
(defn destructure [bindings]
(let [bmap (apply array-map bindings)
pb (fn pb [bvec b v]
(let [pvec
(fn [bvec b val]
(let [gvec (if (symbol? val) val (gensym
"vec__")),
length-val (:length ^val)]
(loop [ret (if (symbol? val) bvec (-> bvec
(conj gvec) (conj val)))
n 0
bs b
seen-rest? false]
(if (seq bs)
(let [firstb (first bs)]
(cond
(= firstb '&) (recur (pb ret (second
bs) (list `nthnext gvec n))
n
(nnext bs)
true)
(= firstb :as) (pb ret (second bs)
gvec)
:else (if seen-rest?
(throw (new Exception
"Unsupported binding form, only :as can follow & parameter"))
(recur (pb ret firstb (if (and
length-val (< n length-val))
(if (or
(vector? val)(= (:tag ^val) :vector))
(list
gvec n)
(list
`nth gvec n))
(list `nth gvec
n nil)))
(inc n)
(next bs)
seen-rest?))))
ret))))
pmap
(fn [bvec b v]
(let [gmap (or (:as b) (if (symbol? v) v
(gensym "map__")))
defaults (:or b)]
(loop [ret (if (symbol? v) bvec (-> bvec
(conj gmap) (conj v)))
bes (reduce
(fn [bes entry]
(reduce #(assoc %1 %2 ((val
entry) %2))
(dissoc bes (key
entry))
((key entry) bes)))
(dissoc b :as :or)
{:keys #(keyword (str %)), :strs
str, :syms #(list `quote %)})]
(if (seq bes)
(let [bb (key (first bes))
bk (val (first bes))
has-default (contains? defaults
bb)]
(recur (pb ret bb (if has-default
(list `get gmap bk
(defaults bb))
(list `get gmap
bk)))
(next bes)))
ret))))]
(cond
(symbol? b) (-> bvec (conj b) (conj v))
(vector? b) (pvec bvec b v)
(map? b) (pmap bvec b v)
:else (throw (new Exception (str "Unsupported
binding form: " b))))))
process-entry (fn [bvec b] (pb bvec (key b) (val b)))]
(if (every? symbol? (keys bmap))
bindings
(reduce process-entry [] bmap))))
;;I wasn't sure how to do a 'vector' (kept getting the 'vector'
function instead) so I just used
;;:vector keyword to dispatch on. Becomes kind of unsafe if you
violate the 'length' promise.
;;this also eliminates a redundancy where you were binding (let [v [1
2 3]] (let [[a b c] v]))
;;and the inner let would have (let [gensym_vec v, a (nth gensym_vec
0)...])
;;as opposed to (let [a (nth v 0)...]...)
;;which should be ok because we don't have to worry about multiple
evaluation if we are destructuring from a symbol.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---