Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
trampoline for mutual recursion
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 31 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Rich Hickey  
View profile  
 More options Nov 25 2008, 9:05 am
From: Rich Hickey <richhic...@gmail.com>
Date: Tue, 25 Nov 2008 06:05:06 -0800 (PST)
Local: Tues, Nov 25 2008 9:05 am
Subject: trampoline for mutual recursion
I've added trampoline to ease the conversion/creation of mutually
recursive algorithms in Clojure.

Trampolines are a well known technique for implementing TCO - instead
of actually making a call in the tail, a function returns the function
to be called, and a controlling loop calls it, thus allowing chained
execution without stack growth.

In order to do this I've made the following changes (SVN 1122):

Added clojure.lang.Fn marker interface, used on all true fns.
Breaking change - fn? now tests for Fn, not IFn (this was frequently
requested)
Added ifn? which will test for anything callable (IFn)
Added trampoline, implements trampoline protocol for TCO

Here's how it works. Normally, if you have mutual recursion (i.e.
which can't be replaced with recur), you can blow the stack:

(declare bar)

(defn foo [n]
  (if (pos? n)
    (bar (dec n))
    :done-foo))

(defn bar [n]
  (if (pos? n)
    (foo (dec n))
    :done-bar))

(foo 1000000)
-> java.lang.StackOverflowError

To convert to a trampoline, simply return closures over your tail
calls, rather than direct calls. This is as simple as prepending #

(declare bar)

(defn foo [n]
  (if (pos? n)
    #(bar (dec n))
    :done-foo))

(defn bar [n]
  (if (pos? n)
    #(foo (dec n))
    :done-bar))

Then make the top-level call via trampoline:

(trampoline #(foo 1000000))
-> :done-foo

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stephen C. Gilardi  
View profile  
 More options Nov 25 2008, 10:42 am
From: "Stephen C. Gilardi" <squee...@mac.com>
Date: Tue, 25 Nov 2008 10:42:30 -0500
Local: Tues, Nov 25 2008 10:42 am
Subject: Re: trampoline for mutual recursion

On Nov 25, 2008, at 9:05 AM, Rich Hickey wrote:

> I've added trampoline to ease the conversion/creation of mutually  
> recursive algorithms in Clojure.

Very cool! Thanks for enabling that.

In looking over the implementation, I found a small problem: the arg  
vector precedes the doc string leading to:

user=> (doc trampoline)
-------------------------
clojure.core/trampoline
([f])
   nil
nil

--Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rich Hickey  
View profile  
 More options Nov 25 2008, 11:07 am
From: Rich Hickey <richhic...@gmail.com>
Date: Tue, 25 Nov 2008 08:07:29 -0800 (PST)
Local: Tues, Nov 25 2008 11:07 am
Subject: Re: trampoline for mutual recursion

On Nov 25, 10:42 am, "Stephen C. Gilardi" <squee...@mac.com> wrote:

> On Nov 25, 2008, at 9:05 AM, Rich Hickey wrote:

> > I've added trampoline to ease the conversion/creation of mutually
> > recursive algorithms in Clojure.

> Very cool! Thanks for enabling that.

> In looking over the implementation, I found a small problem: the arg
> vector precedes the doc string leading to:

Fixed (SVN 1123) - thanks for the report.

I've also added support for passing initial args, so the top-level
call can be:

(trampoline foo 1000000)

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
steven_h@acm.org  
View profile  
 More options Nov 25 2008, 1:22 pm
From: "steve...@acm.org" <steven.hu...@gmail.com>
Date: Tue, 25 Nov 2008 10:22:14 -0800 (PST)
Local: Tues, Nov 25 2008 1:22 pm
Subject: Re: trampoline for mutual recursion

On Nov 25, 11:07 am, Rich Hickey <richhic...@gmail.com> wrote:

I think this will be very useful. Now if only we can convince Sun to
make it unnecessary...

-- Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
samppi  
View profile  
 More options Nov 25 2008, 2:19 pm
From: samppi <rbysam...@gmail.com>
Date: Tue, 25 Nov 2008 11:19:32 -0800 (PST)
Local: Tues, Nov 25 2008 2:19 pm
Subject: Re: trampoline for mutual recursion
Yes, this is superb—I was just now trying to figure out a complicated
tree zipper that mutual recursion would make needless. Thanks a lot!

On Nov 25, 11:22 am, "steve...@acm.org" <steven.hu...@gmail.com>
wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jim  
View profile  
 More options Nov 25 2008, 5:17 pm
From: jim <jim.d...@gmail.com>
Date: Tue, 25 Nov 2008 14:17:02 -0800 (PST)
Local: Tues, Nov 25 2008 5:17 pm
Subject: Re: trampoline for mutual recursion
Very nice.  Thanks, Rich.

I had implemented my own version, but it's much nicer to have it in
the language.

Jim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
kib2  
View profile  
 More options Nov 25 2008, 4:17 pm
From: kib2 <kibleur.christo...@gmail.com>
Date: Tue, 25 Nov 2008 13:17:32 -0800 (PST)
Local: Tues, Nov 25 2008 4:17 pm
Subject: Re: trampoline for mutual recursion
Thanks Rich,

funny, there was a post on trampoline in the Python community today :
http://davywybiral.blogspot.com/2008/11/trampolining-for-recursion.html


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
dreish  
View profile  
 More options Nov 26 2008, 10:28 am
From: dreish <dresweng...@dreish.org>
Date: Wed, 26 Nov 2008 07:28:43 -0800 (PST)
Local: Wed, Nov 26 2008 10:28 am
Subject: Re: trampoline for mutual recursion
Now that you've gone this far, why not do this?

- class clojure.lang.TailCall contains an AFn
- Compiler checks for a tail call position and instead of calling it,
returns new TailCall(AFn)
- In invoke, while returnvalue instanceof TailCall, returnvalue =
returnvalue.fn.invoke(returnvalue)

I confess I don't yet have much familiarity with the compiler; I'm
just reading through it now. Is the above idea workable?

Upside: you could have real TCO tonight, with J2SE 5.

Downside: as soon as they finally get around to putting TCO in the
JVM, it becomes useless cruft.

I would think you could take it back out, though. And who knows when
they'll finally do it? And wouldn't it be better to put TCO workaround
cruft in the compiler, rather than in the language definition, around
which people are already (foolishly, perhaps) starting to build
serious programs?

On Nov 25, 9:05 am, Rich Hickey <richhic...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rich Hickey  
View profile  
 More options Nov 26 2008, 11:14 am
From: Rich Hickey <richhic...@gmail.com>
Date: Wed, 26 Nov 2008 08:14:04 -0800 (PST)
Local: Wed, Nov 26 2008 11:14 am
Subject: Re: trampoline for mutual recursion

On Nov 26, 10:28 am, dreish <dresweng...@dreish.org> wrote:

There's a very simple reason - such built-in trampolines are
incompatible with interoperability. Anyone can build a trampoline
system into their lang to get tail calls and make sure it is used
consistently within lang - but what do those TailCall return values
mean to a Java caller?

Also, in what you've described every invoke turns into a loop, every
tail call allocates etc.

I made a conscious decision here, and it was a pragmatic one. People
using Clojure are pragmatic, not foolish.

The vast majority of tail calls requiring TCO are self-calls handled
by recur.

I'm all for TCO, but trampolines are simplistic TCO and no substitute
for real jumps.

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
dreish  
View profile  
 More options Nov 26 2008, 1:00 pm
From: dreish <dresweng...@dreish.org>
Date: Wed, 26 Nov 2008 10:00:59 -0800 (PST)
Local: Wed, Nov 26 2008 1:00 pm
Subject: Re: trampoline for mutual recursion
On Nov 26, 11:14 am, Rich Hickey <richhic...@gmail.com> wrote:

> There's a very simple reason - such built-in trampolines are
> incompatible with interoperability. Anyone can build a trampoline
> system into their lang to get tail calls and make sure it is used
> consistently within lang - but what do those TailCall return values
> mean to a Java caller?

Thanks. I was uneasy enough about performance, without really
understanding how much of a problem it would be, but interop would be
a deal-killer. Guess it's back to waiting.

From http://blogs.sun.com/jrose/entry/tail_calls_in_the_vm I can at
least hope it's not too far away, although it sounds like it'll never
happen for method calls looked up with reflection.

> The vast majority of tail calls requiring TCO are self-calls handled
> by recur.

My favorite thing about recur is that the compiler tells you
immediately if you accidentally put it somewhere other than in a tail
position. You don't have to wait for the stack to overflow in actual
use because your test case was too small. I would hope the keyword
sticks around even if TCO gets added to the JVM.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chouser  
View profile  
 More options Nov 26 2008, 1:44 pm
From: Chouser <chou...@gmail.com>
Date: Wed, 26 Nov 2008 13:44:36 -0500
Local: Wed, Nov 26 2008 1:44 pm
Subject: Re: trampoline for mutual recursion

On Wed, Nov 26, 2008 at 1:00 PM, dreish <dresweng...@dreish.org> wrote:

> My favorite thing about recur is that the compiler tells you
> immediately if you accidentally put it somewhere other than in a tail
> position. You don't have to wait for the stack to overflow in actual
> use because your test case was too small. I would hope the keyword
> sticks around even if TCO gets added to the JVM.

Hear, hear!  +1  Can I only vote once?  +10

:-)

Hm, maybe a general compile-time assert would be in order, once we
have real tail-call optimization, so that even in the mutual-recursion
case you could get a nice error if you make a mistake like:

(def foo []
  (+ 10
     (tail-call bar 1 2)))

Although something less ugly might be nice.

--Chouser


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Randall R Schulz  
View profile  
 More options Nov 26 2008, 1:56 pm
From: Randall R Schulz <rsch...@sonic.net>
Date: Wed, 26 Nov 2008 10:56:55 -0800
Local: Wed, Nov 26 2008 1:56 pm
Subject: Re: trampoline for mutual recursion
Hi,

On Tuesday 25 November 2008 06:05, Rich Hickey wrote:

> I've added trampoline to ease the conversion/creation of mutually
> recursive algorithms in Clojure.

> ...

Clojure's new trampolines for mutually recursive functions has caught
the attention of the Scala folks. There's a nice thread going on in the
Scala-Debate list beginning with one user's mention of this new
capability in Clojure. Two people there (one of them being Martin
Odersky, the head architect of the Scala language) showed a comparable
solution written in Scala.

Check it out:
- Subject: "Tail calls via trampolining and an explicit instruction"
- <http://dir.gmane.org/gmane.comp.lang.scala.debate>
- <http://www.nabble.com/Scala---Debate-f30218.html>
<http://www.nabble.com/Tail-calls-via-trampolining-and-an-explicit-ins...>

Randall Schulz


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mark Volkmann  
View profile  
 More options Nov 26 2008, 3:22 pm
From: "Mark Volkmann" <r.mark.volkm...@gmail.com>
Date: Wed, 26 Nov 2008 14:22:30 -0600
Local: Wed, Nov 26 2008 3:22 pm
Subject: Re: trampoline for mutual recursion

On Tue, Nov 25, 2008 at 8:05 AM, Rich Hickey <richhic...@gmail.com> wrote:

big snip

> To convert to a trampoline, simply return closures over your tail
> calls, rather than direct calls. This is as simple as prepending #

> (declare bar)

> (defn foo [n]
>  (if (pos? n)
>    #(bar (dec n))

I'm curious about this syntax. I thought if #(function-name args)
creates a closure then I can put one in a variable and execute it
later. I entered this in a REPL.

(def myClosure #(prn "Hello"))

How can I execute the closure in myClosure now?

--
R. Mark Volkmann
Object Computing, Inc.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chouser  
View profile  
 More options Nov 26 2008, 3:26 pm
From: Chouser <chou...@gmail.com>
Date: Wed, 26 Nov 2008 15:26:58 -0500
Local: Wed, Nov 26 2008 3:26 pm
Subject: Re: trampoline for mutual recursion
On Wed, Nov 26, 2008 at 3:22 PM, Mark Volkmann

<r.mark.volkm...@gmail.com> wrote:

> I'm curious about this syntax. I thought if #(function-name args)
> creates a closure then I can put one in a variable and execute it
> laterI entered this in a REPL.

> (def myClosure #(prn "Hello"))

> How can I execute the closure in myClosure now?

user=> (myClosure)
"Hello"

or now,

user=> (trampoline myClosure)
"Hello"

--Chouser


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stephen C. Gilardi  
View profile  
 More options Nov 26 2008, 3:27 pm
From: "Stephen C. Gilardi" <squee...@mac.com>
Date: Wed, 26 Nov 2008 15:27:37 -0500
Local: Wed, Nov 26 2008 3:27 pm
Subject: Re: trampoline for mutual recursion

On Nov 26, 2008, at 3:22 PM, Mark Volkmann wrote:

> I entered this in a REPL.

> (def myClosure #(prn "Hello"))

> How can I execute the closure in myClosure now?

Clojure
user=> (def myClosure #(prn "Hello"))
#'user/myClosure
user=> (myClosure)
"Hello"
nil
user=>

--Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
lpetit  
View profile  
 More options Nov 26 2008, 4:32 pm
From: lpetit <laurent.pe...@gmail.com>
Date: Wed, 26 Nov 2008 13:32:58 -0800 (PST)
Local: Wed, Nov 26 2008 4:32 pm
Subject: Re: trampoline for mutual recursion
On 25 nov, 15:05, Rich Hickey <richhic...@gmail.com> wrote:

> To convert to a trampoline, simply return closures over your tail
> calls, rather than direct calls. This is as simple as prepending #

I've maybe missed something, but will this work if one wants to make
the final return value of the tail call a closure ?
Will the closure not be called by the trampoline ?
(Maybe I've missed something regarding the explanation on Fn / IFn,
not clear to me)

If I'm right, then should there be some "marker" to wrap the returned
closure in, that will be checked by the trampoline for this special
case, which will then unwrap the closure and return it as the final
returned value ?

HTH,

--
Laurent


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stephen C. Gilardi  
View profile  
 More options Nov 26 2008, 4:38 pm
From: "Stephen C. Gilardi" <squee...@mac.com>
Date: Wed, 26 Nov 2008 16:38:50 -0500
Local: Wed, Nov 26 2008 4:38 pm
Subject: Re: trampoline for mutual recursion

On Nov 26, 2008, at 4:32 PM, lpetit wrote:

> I've maybe missed something, but will this work if one wants to make
> the final return value of the tail call a closure ?

Along the same lines of this being a manual way to do TCO, that issue  
will need to be handled manually as well. Here's what (doc trampoline)  
has to say about it:

user=> (doc trampoline)
-------------------------
clojure.core/trampoline
([f] [f & args])
   trampoline can be used to convert algorithms requiring mutual
   recursion without stack consumption. Calls f with supplied args, if
   any. If f returns a fn, calls that fn with no arguments, and
   continues to repeat, until the return value is not a fn, then
   returns that non-fn value. Note that if you want to return a fn as a
   final value, you must wrap it in some data structure and unpack it
   after trampoline returns.
nil

--Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
André Thieme  
View profile  
 More options Nov 26 2008, 5:40 pm
From: André Thieme <splendidl...@googlemail.com>
Date: Wed, 26 Nov 2008 14:40:35 -0800 (PST)
Local: Wed, Nov 26 2008 5:40 pm
Subject: Re: trampoline for mutual recursion

On 26 Nov., 21:26, Chouser <chou...@gmail.com> wrote:

> On Wed, Nov 26, 2008 at 3:22 PM, Mark Volkmann

> <r.mark.volkm...@gmail.com> wrote:

> > I'm curious about this syntax. I thought if #(function-name args)
> > creates a closure then I can put one in a variable and execute it
> > laterI entered this in a REPL.

> > (def myClosure #(prn "Hello"))

> > How can I execute the closure in myClosure now?

Hello Mark, maybe something got mixed up here:
#(prn "Hello") looks like an ordinary anonymous function to me,
and not like a closure.
Well, it depends on how we want to define “closure”.
I think the definition should include that it must be a function
(be it a named or anon one) that closes over some lexical
environment. In my opinion this environment should not be the
trivial one: the empty one.
We could do this, but in that case every function would be a
closure. So from that I would say that the given example was
not for a closure.

Maybe a simple accumulator could work here:
user> (let [acc (ref 0)]
        (defn make-accumulator [n]
          (dosync (ref-set acc n))
          (fn [i]
            (dosync (alter acc + i)))))
#'user/make-accumulator

So, here make-accumulator is a closure.
It closes over acc.
And the anon function that is returned by
make-accumulator is also a closure, as it
also closes over acc.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mark Volkmann  
View profile  
 More options Nov 26 2008, 5:51 pm
From: "Mark Volkmann" <r.mark.volkm...@gmail.com>
Date: Wed, 26 Nov 2008 16:51:55 -0600
Local: Wed, Nov 26 2008 5:51 pm
Subject: Re: trampoline for mutual recursion
On Wed, Nov 26, 2008 at 4:40 PM, André Thieme

Thanks! In the meantime I came up with an even simpler example that
demonstrates capturing a parameter and a local variable in a closure.

(defn greet-closure [name]
  (let [salutation "Hello"]
    #(println salutation name)))
(def my-closure (greet-closure "Mark"))
(my-closure)

outputs "Hello Mark"

--
R. Mark Volkmann
Object Computing, Inc.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Pfeiffer  
View profile  
 More options Nov 27 2008, 5:21 am
From: Robert Pfeiffer <pfeiffer.rob...@googlemail.com>
Date: Thu, 27 Nov 2008 02:21:12 -0800 (PST)
Local: Thurs, Nov 27 2008 5:21 am
Subject: Re: trampoline for mutual recursion
On 26 Nov., 22:38, "Stephen C. Gilardi" <squee...@mac.com> wrote:

>    [..] Note that if you want to return a fn as a
>    final value, you must wrap it in some data structure and unpack it
>    after trampoline returns.

If you want to return sets, keywords, maps, or everything that
implements the fn interface this is also an issue. Does trampolining
on keywords make sense?

Robert Pfeiffer


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Meikel Brandmeyer  
View profile  
 More options Nov 27 2008, 7:06 am
From: Meikel Brandmeyer <m...@kotka.de>
Date: Thu, 27 Nov 2008 04:06:34 -0800 (PST)
Local: Thurs, Nov 27 2008 7:06 am
Subject: Re: trampoline for mutual recursion
Hi,

On 26 Nov., 23:40, André Thieme <splendidl...@googlemail.com> wrote:

> Maybe a simple accumulator could work here:
> user> (let [acc (ref 0)]
>         (defn make-accumulator [n]
>           (dosync (ref-set acc n))
>           (fn [i]
>             (dosync (alter acc + i)))))
> #'user/make-accumulator

> So, here make-accumulator is a closure.
> It closes over acc.
> And the anon function that is returned by
> make-accumulator is also a closure, as it
> also closes over acc.

Maybe I have a wrong understanding of "closure", but
as far as I understand, every function definition in
Clojure - be it defn or #() - finally translates to (fn ...).
And fn creates a closure. In fact #(prn "Hello") closes
over the var "prn". Consider the following example:

(ns foo.bar)

(def my-closure #(prn "Hello"))

(ns yoyo.dyne
  (:refer-clojure
    :exclude (prn)))

(defn prn [x] (clojure.core/prn (str "Modified: " x)))

(foo.bar/my-closure)

According to my understanding the output should
be "Hello".

I think the closure is never "empty". It refers to the
environment used at the closure's creation time.
Whether this environment is accessed or not, is not
very interesting, I think.

Ok. Maybe there are gc issues, so one might want
to optimise this. But a closure which, does not
access the environment at all... What would this
look like and which use would it have?

Sincerely
Meikel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stephen C. Gilardi  
View profile  
 More options Nov 27 2008, 7:13 am
From: "Stephen C. Gilardi" <squee...@mac.com>
Date: Thu, 27 Nov 2008 07:13:39 -0500
Local: Thurs, Nov 27 2008 7:13 am
Subject: Re: trampoline for mutual recursion

On Nov 27, 2008, at 5:21 AM, Robert Pfeiffer wrote:

> If you want to return sets, keywords, maps, or everything that
> implements the fn interface this is also an issue. Does trampolining
> on keywords make sense?

The svn revision that introduced trampoline also introduced a "marker"  
interface "fn" that distinguishes "things ultimately produced by fn"  
and "thinks that can be called". The former are the only things that  
are trampolined. It also changed the behavior if fn? and introduced  
ifn? that know about the difference. Here's an example:

Clojure
user=> (fn? :hi)
false
user=> (fn? #(print "hi"))
true

user=> (ifn? :hi)
true
user=> (ifn? #(print "hi"))
true
user=>

See also:

http://clojure.svn.sourceforge.net/viewvc/clojure?view=rev&revision=1122

--Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Stephen C. Gilardi  
View profile  
 More options Nov 27 2008, 7:16 am
From: "Stephen C. Gilardi" <squee...@mac.com>
Date: Thu, 27 Nov 2008 07:16:20 -0500
Local: Thurs, Nov 27 2008 7:16 am
Subject: Re: trampoline for mutual recursion

On Nov 27, 2008, at 7:13 AM, Stephen C. Gilardi wrote:

> interface "fn" that distinguishes

The interface is "clojure.lang.Fn".

--Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
lpetit  
View profile  
 More options Nov 27 2008, 7:58 am
From: lpetit <laurent.pe...@gmail.com>
Date: Thu, 27 Nov 2008 04:58:36 -0800 (PST)
Local: Thurs, Nov 27 2008 7:58 am
Subject: Re: trampoline for mutual recursion
Thank you for the answer.

Could trampoline benefit for being enhanced by allowing an explicit
"escaping" for a return value of type function (that could also work
for other return types, but would not be necessary for the common
case).

Something like these :

- common usage : as usual
user=> (def myClosure #(prn "Hello"))
#'user/myClosure
user=> (trampoline myClosure)
"Hello"

- explicit escape via a "noboing" (or "stop" or "return" any name you
like) call (works for any return type) :
user=> (def myClosure (noboing #(prn "Hello")))
#'user/myClosure
user=> (trampoline myClosure)
#'user/myClosure

And it could be implemented as :
public final class org.clojure.lang.NoBoingWrapper {
     public final Object returnInstance;
     public NoBoingWrapper(Object returnInstance)
{ this.returnInstance = returnInstance; }

}

(defn noboing [returnInstance] (org.clojure.lang.NoBoingWrapper.
returnInstance))

and the modification of trampoline along these lines :
(defn trampoline [f]
  (let [ret (f)]
     (cond f
       (fn? ret) (recur ret)
       (instance? org.clojure.lang.NoBoingWrapper f) (.returnInstance
f)
       else ret)))

HTH,

--
Laurent

On Nov 26, 10:38 pm, "Stephen C. Gilardi" <squee...@mac.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
lpetit  
View profile  
 More options Nov 27 2008, 8:37 am
From: lpetit <laurent.pe...@gmail.com>
Date: Thu, 27 Nov 2008 05:37:18 -0800 (PST)
Local: Thurs, Nov 27 2008 8:37 am
Subject: Re: trampoline for mutual recursion
On Nov 27, 1:58 pm, lpetit <laurent.pe...@gmail.com> wrote:

> and the modification of trampoline along these lines :
> (defn trampoline [f]
>   (let [ret (f)]
>      (cond f
>        (fn? ret) (recur ret)
>        (instance? org.clojure.lang.NoBoingWrapper f) (.returnInstance
> f)
>        else ret)))

Mmm might read (cond ret   , and also (instance?
org.clojure.lang.NoBoingWrapper ret) (.returnInstance ret) of course,

--
Laurent


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 31   Newer >
« Back to Discussions « Newer topic     Older topic »