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

From: Rich Hickey (rich at richhickey.com)
Date: Wed Nov 28 09:23:57 EST 2007


I'm the author of Clojure. Here's how I would write it in Clojure:

(defn machine [stream]
   (let [step {[:init 'c] :more
               [:more 'a] :more
               [:more 'd] :more
               [:more 'r] :end
               [:end nil] :t}]
     (loop [state :init
            stream stream]
       (let [next (step [state (first stream)])]
         (when next
           (if (eql? next :t)
             (recur next (rest stream))))))))

(machine  '(c a d a d d r ))
-> :t

(machine  '(c a d a d d r r))
-> nil

BTW, what you wrote was correct code - the error was a compiler bug,  
sorry. I appreciate your spending the time to learn enough Clojure to  
write it, and the bug is now fixed.


Rich Hickey

> > But let me ask a question first.  Can you show us the central
> > definition from this paper in Clojure?
> I decided to give it a crack. I think the following should work,
> though it won't compile and the error messages are most unhelpful.
> (What is clojure.lang.Compiler$CompilerException: REPL:2: null
> supposed to mean =S)
> (def machine
>   (let [states {:init (fn [stream]
>                         (cond
>                           ((nil? stream)
>                            nil)
>                           ((eql? (first stream) \c)
>                            [:more (rest stream)])))
>                 :more (fn [stream]
>                         (cond
>                           ((nil? stream)
>                            nil)
>                           ((eql? (first stream) \a)
>                            [:more (rest stream)])
>                           ((eql? (first stream) \d)
>                            [:more (rest stream)])
>                           ((eql? (first stream) \r)
>                            [:end (rest stream)])))
>                 :end (fn [stream]
>                          (cond
>                           ((nil? stream)
>                            :t)))}]
>     (fn [stream]
>       (loop [state :init
>              stream stream]
>         (let [ret ((state states) stream)]
>           (and ret
>             (if (eql? ret :t)
>               :t
>               (recur (ret 0) (ret 1)))))))))
> Of course, at this point you're just emulating TCO.
>     Henk Boom

Posted on the users mailing list.