> So I am reading On Lisp + some blogs while learning Clojure (I know,
> scary stuff :)
>
> Anyway, I've been playing around to see if I can get an anonymous
> recursive function to work, but alas I am still a n00b and not even
> sure what Clojure's approach to this would be.
> How would I do this in Clojure?:
IIUC based on examples involving label and letrec, you want a
recursive function whose name isn't visible outside of some restricted
scope. letfn is analogous to those, and that would look like:
(letfn [(anon [x]
(if (= x 0)
1
(* 2 (anon (dec x)))))]
(anon 5))
> My first attempt:
>
> ((fn [x]
> (if (= x 0)
> 1
> (* 2 (recur (dec z))))) 5)
>
> Then my second:
>
> ((fn [x]
> (let [z (if (= x 0)
> 1
> (* 2 x))]
> (recur (dec z)))) 5)
>
> Ideally one could do:
>
> ((recursive-fn #( if (= % 0) 1 (* 2 %)) (recur it)) 5)
>
>
> Obviously none work, and I believe I understand why. I just don't
> understand how to actually do this or if for some reason Clojure
> avoids this for some reason.
On the other hand, maybe I misunderstood what you're trying to do, in
which case an example of what you mean by "anonymous recursive
function" in another language (CL or Scheme by preference) would help.
<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
<http://rosettacode.org/wiki/Y_combinator#Clojure>
You can't use Clojure's recur as written because it isn't in tail
position--the result of the function isn't just the value of the recur
expression (in the first instance it is (* 2 (recur ...)) however I
note that z is free in that expression, which looks suspicious.
If your goal is to define a function that computes 2^n with
tail-recursion, then consider threading an "accumulator" parameter
through the recursive function; something like this:
((fun [acc x]
(if (= x 0)
acc
(recur (* 2 acc) (dec x))) 1 5)
Of course, you might consider a helper wrapper function that supplies
the 1 "default" accumulator.
Many functional languages optimize tail calls to jmp instructions;
that's hard to do efficiently in general on the JVM because it doesn't
support tail calls. I expect Clojure has designed recur to work the
way it does because some algorithms depend on the tail call
optimization, but the restrictions of recur make it possible to
compile efficiently as a jmp. So it's a nice compromise.
<http://clojure.org/special_forms#Special Forms--(recur exprs*)>
HTH,
Dominic
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> and now corrected!
>
> (defmacro anaphoric-recur [parm-binds expr & parms]
> "An anaphoric recursive function that takes a vector of blind
> bindable vars, an expression that can handle the bindable vars.
> and the parameters. 'self' is used to call the function
> recursively."
> `(letfn [(~'self ~parm-binds
> (do ~expr))]
> (~'self ~@parms)))
>
> > (anaphoric-recur [x] (if (= x 0) 1 (* 2 (self (dec x)))) 5)
> 32
Cool. I'd worry about using ~' to capture variables in a macro, except
rich hickey said that's intentional in
http://markmail.org/message/d6cubdwwxgjq4po6.