Point / Counterpoint

Tim Bray, Jeff Dillon makes a point about cross platform .NET, via Scott Hanselman, Jason Alexander makes another point. The point? If you care about cross platform .NET, there are details you need to pay attention to, and you really shouldn't do dumb things like use the registry. As for "the cost of not being able to do native system programming in pure Java" we already know that pure .NET is a myth, too.

— Gordon Weakliem at permanent link

Writing a State Machine in Scheme

I saw Dave Roberts mentioned Shriram Krishnamurthi's The Swine Before Perl as an example of writing an automaton in Scheme. Unfortunately, you have to piece together the actual macro from the slides, and I had a hard time with this. Shriram provided the answer on the PLT Scheme mailing list:
(define-syntax automaton
  (syntax-rules (-> :)
    [(_ init-state
        (state : (cndn -> new-state) ...) ...)
     (letrec ([state (lambda (stream)
                       (or (empty? stream)
                           (case (first stream)
                             [(cndn) (new-state (rest stream))]
                             ...
                             [else false])))]
              ...)
       init-state)]))
This allows you to define a state machine to recognize a list of symbols that conform to the pattern c[ad]+r like this:
(define a
  (automaton init
             (init : (c -> loop))
             (loop : (a -> loop)
                     (d -> loop)
                     (r -> end))
             (end : )))
And invoke it like this:
> (a '(c d a d r))
#t
> (a '(c d a d r r))
#f
> (a '(c d x))
#f
Shriram makes the point that a Scheme programmer automatically filters out the parentheses at the ends of each line, using indentation as the primary visual cue. However, the -> and : tokens help a bit too. I showed this to a friend and he remarked how terse it was; commenting that terse is good as long as it's readable. If you want, you can change the tokens. Let's say you want to use a more verbose syntax, something like state if-I-encounter (token transition-to new-state):
(define-syntax wordy-automaton
  (syntax-rules (transition-to if-I-encounter)
    [(_ init-state
        (state if-I-encounter (cndn transition-to new-state) ...) ...)
     (letrec ([state (lambda (stream)
                       (or (empty? stream)
                           (case (first stream)
                             [(cndn) (new-state (rest stream))]
                             ...
                             [else false])))]
              ...)
       init-state)]))

(define b
  (wordy-automaton init
                   (init if-I-encounter (c transition-to loop))
                   (loop if-I-encounter (a transition-to loop)
                         (d transition-to loop)
                         (r transition-to end))
                   (end if-I-encounter )))
I just think this is a really cool example of what it really means to be able to define your own language in Lisp.

— Gordon Weakliem at permanent link