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 On Jun 30, 2:13 pm, Tim Robinson <tim.blacks...@gmail.com> wrote: > Thanks for all the replies. Sorry if my responses are delayed. I'm > still on newb moderation mode, so I find my response can take 2 - 10 > hours to be published. > > > note that z is free in that expression, which looks suspicious. > > yup, it was supposed to be x. It was a copy paste error. I normally > would evaluate the function, but in this case I was expecting errors. > > As for acc or other options, I was hoping to create a recursive fn > that could generically accept an anonymous function as an argument, > which was what I was > thinking. > > Using a form like: > > ((recursive-fn #(do-stuff (self (dec %))) (recur self)) 5) > > (obviously not the way - just the notion) > > kind of thing. > > When I am home tonight I can play aorund with the examples provided. > > Thanks, > Tim > > On Jun 30, 8:59 am, Dominic Cooney <dominic.coo...@gmail.com> wrote: > > > > > If you name the Y combinator, then you can write recursive anonymous > > functions: > > > <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#SpecialForms--(recurexprs*)> > > > HTH, > > > Dominic > > > On Wed, Jun 30, 2010 at 2:44 PM, Tim Robinson <tim.blacks...@gmail.com> > > wrote: > > > 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?: > > > > 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. > > > > I am not actually trying to accomplish a specific task, so the example > > > was made to be simple not meaningful. I'm just playing around to learn > > > recursive functions and Clojure style. > > > > Thanks, > > > Tim > > > > -- > > > 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 > > > Note that posts from new members are moderated - please be patient with > > > your first post. > > > 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 -- 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 Note that posts from new members are moderated - please be patient with your first post. 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