On Jan 11, 7:09 pm, e <evier...@gmail.com> wrote:
> if it has tighter scope, then I don't understand why you don't have an
> infinite loop.  The nested my-list that you redefined should have
> nothing to do with the my-list that you are doing the 'rest' check
> on.

That's what the loop/recur form does. Again, loop/recur can be defined
in terms of functions:

(defn f [xs]
  (loop [ys xs, s 0]
    (if ys
      (recur (rest ys) (+ s 1))
      s)))

Is equivalent to the following Python:

def f(xs):
  def g(ys, s):
    if ys:
      return g(xs[1:], s + 1)
      return s
  return g(xs, 0)

When recur is called, it acts similarly to a recursive call. The loop
part defines the arguments the loop acts on. The recur part signifies
the loop should be repeated with new arguments. Just like the inner
function, g.

So in my previous code, it's true that the new my-list has a small
scope. But I pass it back to the loop which defines a new variable,
also called my-list, for the next iteration.

I guess it would be clearer if I used different names:

(defn msort [some-list]
  (loop [list-A (vec (map vector some-list))]
    (if (rest my-list)
      (let [[l1 l2 & list-B] list-A
            list-merge      (some-merge-function l1 l2)
            list-C          (conj list-B list-merge)]
        (recur list-C))
      (first my-list))))

So list-A is used to make list-B, which is used to make list-C, and on
the next iteration of the loop, list-C becomes bound to list-A again.

> that must be some magic about the loop construct.  I dunno.  I'm still
> confused.  Every version of the python code makes sense.  I've got
> this reference to my-list, and I can change that reference.  I see the
> same thing happening here, but it's scoped inside a let barrier.

Basically, everything to do with scoping in Lisp can be explained in
terms of functions:

(let [x y] ...)
=
((fn [x] ...) y)

(loop [x y]
  (recur x)
=
(defn f [x]
  (f x)

Though loop and let are more efficient than their function
equivalents.

- James
--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to