Usability issue Andre van Tonder 09 Aug 2004 14:05 UTC

I have recently had the occasion to attempt to use a (refined) version of this
SRFI to implement a nontrivial records proposal.  In the end I had to
abandon computation-rules and use a more primitive continuation-passing
style instead

  (see http://groups.google.com/groups?selm=4112BD31.CA50FB3A%40het.brown.edu)

because of the following important usability issue:

The following common patterns in these kinds of macros do not
work:

  (syntax-bind ((x (long-computation)))
     (syntax-return
        (begin (define f ( ....... x ......))
               (define g ( ....... x ......))
               ...))))

or

  (syntax-bind ((names (long-computation)))
     (syntax-return (emit-definitions names)))

where

  (emit-definitions name ...) =
     (begin (define name ..............)
            ...))

The problem in both of these macros is that syntax-bind has to substitute
x or names in its body, for which it needs the following
macro, which tests for bound equivalence of identifiers:

(define-syntax bound=
  (syntax-rules ()
    ((bound= id b kt kf)
      (letrec-syntax
          ((id (syntax-rules ()
                 ((id kt* kf*) kf*)))
           (ok (syntax-rules ()
                 ((ok kt* kf*) kt*)))
           (test (syntax-rules ()
                   ((_ b kt* kf*) (id kt* kf*))))
        (test ok kt kf))))))

Because the continuations are expanded in the scope of the
letrec-syntax, some Schemes (e.g. MzScheme, but not Chez)
regard any definitions in the result as internal.  This is in my
opinion a conceptual error, but it is compatible with R5RS, which
does not fix the behavior.

Since the only way to portably define bound= is in terms of let-syntax,
this problem, unless resolved, in my view severely restricts the usability
of this SRFI.

The problem can be trivially fixed in MzScheme by defining bound=
as follows instead:

(define-syntax bound=
  (lambda (stx)
    (syntax-case stx ()
      ((_ id b kt kf)
       (if (bound-identifier=? (syntax id) (syntax b))
           (syntax kt)
           (syntax kf))))))

but that conflicts with the aim of making this SRFI portable, as it
would require some implementor effort in Schemes that do not expose
an equivalent of bound-identifier=?   What is worse, we cannot specify
the semantics of computation-rules on the basis of syntax-rules, which
was originally my aim.  It is also likely that future refinements of
R5RS will go the MzScheme way, which will indeed make it impossible
to define a useful bound= in terms of syntax-rules (unless
bound= and free= are offered as primitives, which would be a simple
but useful extension of the standard).

I am therefore in a bit of a quandary.  I would like to be able to offer
a nontrivial example (such as the records implementation referred to above)
before completing this SRFI.  At present, this is impossible to do
portably.

------------- End Forwarded Message -------------