[plt-scheme] stupid Swindle tricks

From: Eli Barzilay (eli at barzilay.org)
Date: Fri May 26 14:24:09 EDT 2006

On May 26, Doug Orleans wrote:
> Eli Barzilay writes:
>  > On May 26, Doug Orleans wrote:
>  > > Candidates for swindle/misc.ss, in decreasing order of usefulness:
>  > > 
>  > >   (defsyntax* set-if!
>  > >     (syntax-rules ()
>  > >       ((_ condition then-place else-place val)
>  > >        (if condition (set! then-place val) (set! else-place val)))))
>  > 
>  > I thought about adding that at the time, but there was some
>  > reason not to do it.  Possibly the double code output in `val'.
> 
> Unfortunately, (set! (cond ...) val) doesn't seem to work, even if
> you define set-begin! and set-#%top!.  Probably because the macros
> come from a different place.

Probably because `#%top' is used in a different way than other forms
-- it's (#%top . foo) and not (#%top foo).


> Anyway, this isn't earth-shatteringly useful, but I thought it was a
> cute hack.

Here's another point where this hack suffers (and probably the reason
I didn't add it) -- some things that rely on `set!' assume that
everything in the form is simple values.  When you try:

  (inc! (if (zero? (random 2)) a b))

you'll see that it doesn't work.  Expanding that once shows that it
transforms to:

  (let ((g39 (zero? (random 2)))
        (g40 a)
        (g41 b))
    (setf! (if g39 g40 g41) (+ (if g39 g40 g41) 1)))

In general, this is the right thing -- you want to evaluate all
`index' arguments once, but `if' is not a function, so it ends up
incrementing the locals instead.

(Maybe there's some good PLAI lesson here...)


>  > >   (defsyntax* last-of
>  > >     (syntax-rules ()
>  > >       ((_ successor first clause ...)
>  > >        (collect (x first (successor x)) clause ...))))
> 
> I think this is useful.  Maybe it needs a better name.  I think it's
> a good abstraction of "apply a function repeatedly and return the
> last result" (where "last" is defined by the conditions in the other
> clauses).

And that separation of `apply a function' (a plain Scheme concept) and
`last' (some mess that `collect' can parse) is what bugs me.  I;d
separate them into

  (let loop ([x first])
    (if (??? x)
      x
      (loop (successor x))))

and

  (defsubst (last-of empty expr clause ...)
    (collect (x empty expr) clause ...))


> The rest of the stuff I posted is mostly just one particular use for
> this, but those are probably too contrived.  (It was late at night,
> I was a little loopy...)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.