[plt-scheme] Android; compiling to Java byte code; Clojure

From: Benjamin L. Russell (dekudekuplex at yahoo.com)
Date: Sat Nov 24 15:01:16 EST 2007

Okay, so, to sum, you would like to see a Clojure
version of your implementation of an automaton to
recognize the language 

  c(ad)*r

written textually as

  automaton init
    init : c -> more
    more : a -> more
           d -> more
           r -> end
    end  :

where your Scheme version, as outlined in "Fig. 1.
Implementation of an Automaton," is as follows:

(define machine
  (letrec ([init
          (lambda (stream)
            (cond
              [(empty? stream) true]
              [else
              (case (first stream)
                [(c) (more (rest stream))]
                [else false])]))]
          [more
          (lambda (stream)
            (cond
              [(empty? stream) true]
              [else
              (case (first stream)
                [(a) (more (rest stream))]
                [(d) (more (rest stream))]
                [(r) (end (rest stream))]
                [else false])]))]
          [end
          (lambda (stream)
            (cond
              [(empty? stream) true]
              [else
              (case (first stream)
                [else false])]))])
  init))

I suppose a Clojure version could be written somewhat
similarly to the following (forgive me if the
following code has errors; I am not fully familiar
with the syntax of Clojure, so some of the special
form names may be different, and am doing this
immediately after reading your paper and comparing it
to the definitions listed in the Clojure Web site at
http://clojure.sourceforge.net/):

(def machine [stream]
  (let [fn [init stream]
            (cond
              [(empty? stream) true]
              [else
              (case (first stream)
                [(c) (more (rest stream))]
                [else false])])])
       [fn [more stream]
           (cond
             [(empty? stream) true]
             [else
             (case (first stream)
               [(a) (recur (rest stream))]
               [(d) (recur (rest stream))]
               [(r) (recur (rest stream))]
               [else false])]))]
       [fn [end stream]
           (cond
             [(empty? stream) true]
             [else
             (case (first stream)
               [else false])])])
  (init))

According to "Differences with other lisps | Clojure"
( see
http://clojure.sourceforge.net/reference/lisps.html ),


> * There is no tail-call optimization, use recur.
> * lambda is fn, and supports overloading by arity
> * No letrec, labels or flet - use thisfn.

Therefore, I have substituted fn for lambda, and let
for letrec (while using recur), in the above.

(I haven't tested this yet, so forgive me if this does
not work.  I hope to refine this later when I have
more time.)

The Clojure Web site states the following with regard
to recur ( see
http://clojure.sourceforge.net/reference/special_forms.html
):

> 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.

It seems (at least to me, but I could be wrong) that,
in the above, in "(fn more)," recur would bind "(rest
stream)" to the parameter "stream" of the "(fn [more
stream])" call.  Since by definition, recur rebinds
the parameters if the recursion point was a fn method,
there should be no need for a letrec, which would
normally be necessary in a definition of a recursive
local procedure.

Does this make any sense, or am I missing something?

Benjamin L. Russell

--- Shriram Krishnamurthi <sk at cs.brown.edu> wrote:

> > 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?
> 
> Yes, and with bells on!
> 
> But let me ask a question first.  Can you show us
> the central
> definition from this paper in Clojure?
> 
>
http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros/
> 
> [I think this example is not so hard with RECUR, but
> I'd like to see
> it done anyway.]
> 
> Thanks,
> Shriram
> 




Posted on the users mailing list.