Hi Achim,

On Sun, Aug 31, 2008 at 1:58 PM, Achim Passen <[EMAIL PROTECTED]> wrote:

> Now suppose you want to define a function which returns the nth
> fibonacci number, but you down want "fibs" around globally. My guess
> was:
>
>        (defn fib [n]
>          (let [fibs2 (lazy-cat '(0 1) (map + fibs2 (drop 1 fibs2)))]
>            (nth fibs2 n)))
>
> But this yields "Unable to resolve symbol: fibs2 in this context", so
> let doesn't allow being self-referential the way def does. I don't
> quite understand why the second arg to lazy-cat is being evaluated in
> the first place. Shouldn't evaluation be delayed until needed?
>
> Does anyone know how to get around this?

You can create locally recursive functions by writing an inline (fn
..) form with a name. So your example above becomes:

(defn fib [n]
  (let [fibs2 (fn fibs2 [] (lazy-cat '(0 1) (map + (fibs2) (drop 1 (fibs2)))))]
    (nth (fibs2) n)))

So instead of defining fibs2 as a lazy-cat directly, we wrap it in a
function that when called returns the lazy-cat you are trying to
define. Note that the inline (fn) form has a symbol inserted before
its argument list:

 (fn fibs2 [] (lazy-cat ...)))

This allows an anonymous function to refer to itself. Then we just
need to replace each use of fibs2 with a call to the wrapper instead
of a direct reference to the lazy-cat--each reference to fibs2 becomes
a call to (fibs2).

Results:

user> (fib 0)
0
user> (fib 1)
1
user> (fib 2)
1
user> (fib 3)
2
user> (fib 4)
3
user> (fib 5)
5

There might be a cleaner way to do this, I'm not sure. This was the
first idea that popped into my head :).

/mike.

--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to