Ooops - my apologies (attempted correction below)
Here is a horribly contrived example (sorry, that's all I can come up
withht now rig) using recur across different arities of the same function,
together with trampoline.
(defn is-odd?
([n]
(cond (< n 0) true
(even? n) #(is-odd? (dec n) true)
:else (recur (- n 2))))
([n even?]
(cond
even? #(not (is-odd? (dec n)))
(< n 0) true
(zero? n) false
:else (recur (- n 2) false))))
=>(trampoline is-odd? 3)
=> true
=>(trampoline is-odd? 40)
=> false
=>(trampoline is-odd? 41 false)
=> true
So I don't see why you can't avoid stack consumption using recur anywhere,
including across multiple arities with trampoline - just wrap the whole
thing in a trampoline call e.g. in andmed's example:
(although I don't understand the logic well)
...
(defn find-comment-in-line
([s] (when (pos? (count s))
(if-let [cs (seq (comment-s? s))]
(subs s (count (first cs)))
(if-let [qs (seq (quote-s? s))]
#(find-comment-in-line (subs s 1) qs)
(recur (subs s 1))))))
([s q] (when (pos? (count s))
(if-let [qs (seq (quote-s? s))]
(if (= qs q)
#(find-comment-in-line (subs s 1))
(recur (subs s 1) q))))))
=> (trampoline find-comment-in-line ...)
On Wednesday, April 20, 2016 at 4:26:21 PM UTC-4, [email protected]
wrote:
>
> I don't think you're missing anything James. It does not look like this
> example uses trampoline with the intended effect.
>
> On Wednesday, April 20, 2016 at 2:45:05 PM UTC-4, James Elliott wrote:
>>
>> Does trampoline really help in this case? I don’t see where we are ever
>> returning a new function for trampoline to call, avoiding a new stack
>> frame. It seems to me no different than simply calling the other arities
>> directly in this example. What am I missing?
>>
>> On Wednesday, April 20, 2016 at 12:00:35 PM UTC-5, J.-F. Rompre wrote:
>>>
>>> You can prevent stack consumption by using trampoline for tail-recursive
>>> calls to a different arity, and recur for same arity, something like:
>>>
>>> (defn find-comment-in-line
>>>
>>> ([s] (when (pos? (count s))
>>> (if-let [cs (seq (comment-s? s))]
>>> ;; yes, a comment symbol found,
>>> ;; just return the remainder of a string
>>> (subs s (count (first cs)))
>>>
>>> ;; no, lets check for an opening quote
>>>
>>> (if-let [qs (seq (quote-s? s))]
>>>
>>> ;; yes, an opening quote found,
>>> ;; now go look for an end quote
>>> (trampoline find-comment-in-line (subs s 1) qs)
>>>
>>> ;; no, just some other symbol found,
>>> ;; check for the rest
>>> (recur (subs s 1))))))
>>>
>>> ([s q] (when (pos? (count s))
>>> ;; lets check if it is a quote
>>> (if-let [qs (seq (quote-s? s))]
>>>
>>> ;; is it a closing quote?
>>> (if (= qs q)
>>> ;; yes, lets check for the rest
>>> (trampoline find-comment-in-line (subs s 1))
>>>
>>> ;; no, just ignore the symbol,
>>> ;;continue looking for a closing quote
>>> (recur (subs s 1) q))))))
>>>
>>>
>>>
>>> On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:
>>>>
>>>> Thank you. That the point. If "recur" binds to fn, why it can not know
>>>> the binding point as the function method based on the number of arguments
>>>> passed to it? I mean it is clear that Clojure can't do that, but I can see
>>>> no reason why it could or should not if we choose to implement such
>>>> syntactic nicety as recur in a function
>>>>
>>>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.