[plt-scheme] Android; compiling to Java byte code; Clojure
According to the Clojure Web site, "There is no
tail-call optimization, use recur." ( See
http://clojure.sourceforge.net/reference/lisps.html .)
Here is what their site says about recur ( see
http://clojure.sourceforge.net/reference/special_forms.html
):
> (recur exprs*)
>
> Evaluates the exprs in order, then, in parallel,
> rebinds the bindings of the recursion point to the
> values of the exprs. If the recursion point was a fn
> method, then it rebinds the params. If the recursion
> point was a loop, then it rebinds the loop bindings.
> Execution then jumps back to the recursion point.
The
> recur expression must match the arity of the
> recursion point exactly. In particular, if the
> recursion point was the top of a variadic fn method,
> there is no gathering of rest args - a single seq
(or
> null) should be passed. recur in other than a tail
> position is an error.
>
>
> Note that recur is the only non-stack-consuming
> looping construct in Clojure. There is no tail-call
> optimization and the use of self-calls for looping
of
> unknown bounds is discouraged. recur is functional
> and its use in tail-position is verified by the
> compiler.
>
> (def factorial
> (fn [n]
> (loop [cnt n acc 1]
> (if (zero? cnt)
> acc
> (recur (dec cnt) (* acc cnt))))))
The special form loop binds cnt to n and acc to 1.
Notice the lack of explicit recursion in the above
procedure, and the loop special form.
For reference, here's their description of the let
special form:
> (loop [bindings* ] exprs*)
>
> Loop is exactly like let, except that it establishes
> a recursion point at the top of the loop, with arity
> equal to the number of bindings. See recur.
Compare their above procedure with the tail-recursive
version of the same function in SICP ( see
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.1
):
> (define (factorial n)
> (fact-iter 1 1 n))
>
> (define (fact-iter product counter max-count)
> (if (> counter max-count)
> product
> (fact-iter (* counter product)
> (+ counter 1)
> max-count)))
It seems to me that recur and loop together allow a
more intuitive version of the equivalent of tail
recursion in this case than the regular tail recursion
in the equivalent SICP Scheme version.
Any opinions?
Benjamin L. Russell
--- "Geoffrey S. Knauth" <geoff at knauth.org> wrote:
> During the discussion of Google's Android Open
> Handset Alliance
> Project, Noel Welsh commented, "the route to getting
> Scheme code onto
> Android is to compile to Java bytecode."
>
> Begin forwarded message:
>
> > From: Heow Eide-Goodman <lists at alphageeksinc.com>
> > Date: November 21, 2007 16:46:57 EST
> > To: "lisp at lispnyc.org" <lisp at lispnyc.org>
> > Subject: [Lisp] Clojure Resources
>
> If you missed the Clojure presentation, you missed a
> treat.
>
> Rich Hickey presented the culmination of many years
> of work into his new
> dynamic lisp-like language.
>
> Not only does it support a REPL, but everything is
> dynamicly compiled
> into Java byte-code on the fly. There really is no
> interpreter!
>
> Besides performance, Clojure supports run-time
> polymorphism and an
> impressive take on making concurrent programming
> easy by the use of
> software transactional memory.
>
> Slides and audio coverage are available here:
>
> http://lispnyc.org/wiki.clp?page=past-meetings
>
> _________________________________________________
> For list-related administrative tasks:
>
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>