You really do need to know a little bit about phases in order to develop macros in Racket, so just putting a band-aid on the issue wouldn't be much help, and the apparent departure from the normal rules would just make it more difficult to understand phases by looking at the requires of a working program.

For example, you might expect this to work:

  (require 'sp)

  (define-syntax-class binding
    (pattern (var:id rhs:expr)))

  (define-syntax (mylet stx)
    (syntax-parse stx
      [(_ (b:binding ...) body ...+)
       #'((lambda (b.var ...) body ...) b.rhs ...)]))

But it doesn't, because binding is a phase-0 syntax class and the macro needs a phase-1 syntax-class. You still have to think about phases.

Compare with:

  (require (for-syntax syntax/parse))

  (begin-for-syntax
   (define-syntax-class binding
     (pattern (var:id rhs:expr))))

  (define-syntax (mylet stx)
    (syntax-parse stx
      [(_ (b:binding ...) body ...+)
       #'((lambda (b.var ...) body ...) b.rhs ...)]))

The syntax-parse library is required at phase 1 (with for-syntax). The define-syntax-class form is used at phase 1 (in a begin-for-syntax). The syntax-parse form is used at phase 1 (rhs of define-syntax). They're all consistent.

IMO, the clarity is worth the extra verbiage.

Ryan


On 09/24/2013 03:20 PM, Nick Sivo wrote:
Why doesn't syntax/parse just provide everything at phases 0 and 1
like the module 'sp below:

(module sp racket/base
   (require syntax/parse
            (for-syntax syntax/parse))
   (provide (all-from-out syntax/parse)
            (for-syntax (all-from-out syntax/parse))))

(require 'sp)

(define-syntax (mylet stx)
   (syntax-parse stx
                 [(_ ([var-id rhs-expr] ...) body ...+)
                  #'((lambda (var-id ...) body ...) rhs-expr ...)]))

I've not done as much Racket programming as many of you, but I've yet
to want syntax/parse in only phase 0.

-Nick

On Tue, Sep 24, 2013 at 10:21 AM, Laurent <laurent.ors...@gmail.com> wrote:
This is a quite common pitfall into which I have myself fallen a few times,
and I guess it's not the last time.

How much work would be required to prevent people from falling into it ever
again?
Maybe saying so in the docs at the right place wouldn't hurt, but people may
still miss it.
Maybe making the error message more specific like "Did you forget to
(require (for-syntax syntax/parse)) ?" ? Or is it too specific?
Or pushing the idea further (and requiring more work, obviously), Racket's
errors could propose a list of packages where the unknown identifier can be
found, along with the require phase? Is xref able to do that currently?

Laurent



On Tue, Sep 24, 2013 at 6:20 PM, Stephen Chang <stch...@ccs.neu.edu> wrote:

You need (require (for-syntax syntax/parse)) because you are using it
inside a define-syntax.

On Sep 24, 2013 11:56 AM, "Konrad Hinsen" <konrad.hin...@fastmail.net>
wrote:

Hi everyone,

I am trying to learn about syntax-parse, starting with the introduction
of the "Syntax" documentation.

Unfortunately, the very first example given for the use of syntax-parse
doesn't work in my Racket installation:

    Welcome to Racket v5.90.0.9.
    racket@> (require syntax/parse)
    racket@> (define-syntax (mylet stx)
                 (syntax-parse stx
                   [(_ ([var-id rhs-expr] ...) body ...+)
                    #'((lambda (var-id ...) body ...) rhs-expr ...)]))
    stdin::277: _: wildcard not allowed as an expression
      in: (_ ((var-id rhs-expr) ...) body ...+)
      errortrace...:
      context...:
       try-next

/Users/hinsen/Development/racket/pkgs/errortrace-pkgs/errortrace-lib/errortrace/errortrace-lib.rkt:480:4

/Users/hinsen/Applications/Racket/collects/racket/private/misc.rkt:87:7

I tried replacing the wildcard by "mylet", but that only leads to another
error
message:

    racket@> (define-syntax (mylet stx)
                 (syntax-parse stx
                   [(mylet ([var-id rhs-expr] ...) body ...+)
                    #'((lambda (var-id ...) body ...) rhs-expr ...)]))
    stdin::842: ...: ellipses not allowed as an expression
      in: ...
      errortrace...:
      context...:
       try-next

/Users/hinsen/Development/racket/pkgs/errortrace-pkgs/errortrace-lib/errortrace/errortrace-lib.rkt:480:4

/Users/hinsen/Applications/Racket/collects/racket/private/misc.rkt:87:7

Am I doing something wrong here? Or are the examples obsolete?

Konrad.
____________________
   Racket Users list:
   http://lists.racket-lang.org/users

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to