On Jun 23, 2009, at 6:22 PM, pupsik wrote:

The following recursive function does not
terminate if I exexute it in my REPL.
What is wrong?
(This example is from the official Clojure-website).

(defn my-zipmap [keys vals]
 (loop [my-map {}
        my-keys (seq keys)
        my-vals (seq vals)]
   (if (and my-keys my-vals)
     (recur (assoc my-map (first my-keys) (first my-vals))
            (rest my-keys)
            (rest my-vals))
     my-map)))

(my-zipmap [:a :b :c] [1 2 3])

The example needs to be updated for the lazier seqs that were implemented before the Clojure 1.0 release. As part of that change, we lost "nil punning". "rest" no longer returns nil if there are no more items. A new function "next" does though:

user=> (source zipmap)
(defn zipmap
  "Returns a map with the keys mapped to the corresponding vals."
  [keys vals]
    (loop [map {}
           ks (seq keys)
           vs (seq vals)]
      (if (and ks vs)
        (recur (assoc map (first ks) (first vs))
               (next ks)
               (next vs))
        map)))
nil
user=> (doc rest)
-------------------------
clojure.core/rest
([coll])
Returns a possibly empty seq of the items after the first. Calls seq on its
  argument.
nil
user=> (doc next)
-------------------------
clojure.core/next
([coll])
  Returns a seq of the items after the first. Calls seq on its
  argument.  If there are no more items, returns nil.
nil

This is the example that needs updating at clojure.org:

http://clojure.org/functional_programming#toc7

--Steve

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to