On Dec 28 2009, 7:03 am, Konrad Hinsen <konrad.hin...@fastmail.net> wrote: > On 27.12.2009, at 01:47, samppi wrote: > > > creates a new rule that repeats a given subrule. The problem with rep+ > > right now is that it increases the stack for every token it consumes, > > which overflows the stack with large amounts of tokens. > > > Is there, then, a way to rewrite rep+ so that it does not grow the > > stack? > > I don't see one immediately. The problem is not really related to > monads, it's that your rep+ is recursive but not tail-recursive. Tail- > recursive monadic functions can be handled using lazy evaluation, but > this simple solution does not work in your case. Your rep+ needs to be > written in a very different way. > > One idea: if you can express rep+ in terms of m-until, you can then > use the specialized version state-m-until that is not recursive any > more. > > Konrad.
I also found this problem with Jim Duey's none-or-more and one-or- more. After finding this post I took Konrad's advise and came up with this: (defn none-or-more2 "Makes a parser repeat none or more times." [mv] (state-m-until #(:done (meta %)) #((fn [s] (if-let [x (mv s)] [(conj % (first x)) (second x)] [(with-meta % {:done true}) s]))) #^{:done false} [])) Not liking the metadata solution I hacked this up: (defn none-or-more "Makes a parser repeat none or more times." [mv] (fn [s1] (let [[v s2] ((state-m-until first #(fn [s3] (if-let [x (mv s3)] [[false (conj (second %) (first x))] (second x)] [[true (second %)] s3])) [false []]) s1)] [(second v) s2]))) I'd like to see what you guys think and if anyone can clean these up more. -- 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