For Programmers: Free Programming Magazines  


Home > Archive > Scheme > February 2005 > Syntax-rules









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Syntax-rules
Ulrich Hobelmann

2005-02-19, 3:58 am

I'm trying to figure out the basics of syntax-rules, but there is
*nothing* on the web, no simple examples (or I'm too stupid to find them).

I tried a simple example and I don't know why it fails:
(define-syntax defstr
(syntax-rules ()
((defstr name field ...)
(let ((len (length (list field ...))))
(define name len)))))

,expand (defstr foo 1 2 3)
in scheme48 gives me:
Warning: ill-formed definition
(#{Generated define 296} foo #{Generated len 296})
'((lambda (#(>> defstr len 296)) 'syntax-error) (length (list 1 2 3)))

For some reason
(define-syntax defstr
(syntax-rules ()
((defstr name field ...)
(define name (list field ...)))))

works and produces (define foo (list 1 2 3)).

What's wrong with my code?
And how do I specify what code gets evaluated at expand-time and what is
inserted as quoted code (analog to simple Lisp macros)?

Ulrich
mhartl@post.harvard.edu

2005-02-19, 3:58 am

I can't answer your questions, but here's a reference that might help:

http://www.scheme.com/tspl/syntax.html

Michael

Jens Axel Søgaard

2005-02-19, 8:56 am

Ulrich Hobelmann wrote:

> I'm trying to figure out the basics of syntax-rules, but there is=20
> *nothing* on the web, no simple examples (or I'm too stupid to find the=

m).

<http://schemecookbook.org/view/Cook...ngStartedMacros>

> I tried a simple example and I don't know why it fails:
> (define-syntax defstr
> (syntax-rules ()
> ((defstr name field ...) =20
> (let ((len (length (list field ...))))
> (define name len)))))


The problem is nothing more than a forgotten parenthesis.
The syntax if syntax-rules is

(define-syntax <name>
(syntax-rules (<literals> )
((<pattern>
<template> )
...))

In the above the (defstr name field ...) is the
pattern and the template is (let ((len (length (list field ...))))
which means that (define name len) doesn't fit the syntax.


Try using (defstr (name field ...)
(let ((len (length (list field ...))))
in stead.

> What's wrong with my code?
> And how do I specify what code gets evaluated at expand-time and what i=

s=20
> inserted as quoted code (analog to simple Lisp macros)?


Syntax-rules macros can't evaluate code at expand-time. If you need
that, you need to use another macro system. In Scheme48 that
macro system is syntactic closures.

--=20
Jens Axel S=F8gaard

Felix Klock

2005-02-19, 3:58 pm


Ulrich Hobelmann wrote:
> I'm trying to figure out the basics of syntax-rules, but there is
> *nothing* on the web, no simple examples (or I'm too stupid to find

them).

Joe Marshall has a syntax-rules tutorial at the following url:

http://home.comcast.net/~prunesquallor/macro.txt

I don't know if these qualify as "simple examples", but I thought
someone should point it out.

-Felix

Taylor Campbell

2005-02-19, 3:58 pm

On 2005-02-19 06:00:30 -0500, =?ISO-8859-1?Q?Jens_Axel_S=F8gaard?=
<usenet@soegaard.net> said:

> Ulrich Hobelmann wrote:
>
>
> The problem is nothing more than a forgotten parenthesis.
> The syntax if syntax-rules is
>
> (define-syntax <name>
> (syntax-rules (<literals> )
> ((<pattern>
> <template> )
> ...))
>
> In the above the (defstr name field ...) is the
> pattern and the template is (let ((len (length (list field ...))))
> which means that (define name len) doesn't fit the syntax.


That's not at all the case. The original use of SYNTAX-RULES had the
correct form:

(SYNTAX-RULES (<literal> ...)
(<pattern> <template> )
...)

which does _not_ have an extra pair of parentheses surrounding the list
of pattern/template pairs. The LET also had the correct syntax; there
was no incorrect placement of parentheses there. It was the location
of DEFINE that caused a problem. In internal contexts (i.e. bodies of
LAMBDAs, LETs, &c.), definitions must be followed by expressions. It
wasn't a problem of the use of SYNTAX-RULES at all but instead the use
of definitions. You can't do this, either:

(LET ((LEN (LENGTH (LIST 1 2 3))))
(DEFINE FOO LEN))

because DEFINE is not allowed in that context. This may seem strange
at first, but note that internal definitions don't do the same thing as
top-level definitions: they don't introduce new bindings at the top
level, but instead create local recursive bindings, just like LETREC.
I assume you wanted to introduce a top-level binding, in which case
you would need to use a top-level definition. You might use this form
instead:

(DEFINE name (LET ((LEN (LENGTH (LIST item ...)))) LEN))

or simply

(DEFINE name (LENGTH (LIST item ...)))

> s
>
> Syntax-rules macros can't evaluate code at expand-time. If you need
> that, you need to use another macro system. In Scheme48 that
> macro system is syntactic closures.


This statement is incorrect, too. Scheme48 does not support syntactic
closures. It instead supports the explicit renaming macro system,
system, described in

<http://www.bloodandcoffee.net/campb...er91exrename.ps>

(also in a few different formats in the same directory there)

Ulrich Hobelmann

2005-02-19, 8:58 pm

Thanks for the pointers to all!
Anton van Straaten

2005-02-20, 3:58 pm

Ulrich Hobelmann wrote:
> And how do I specify what code gets evaluated at
> expand-time and what is inserted as quoted code
> (analog to simple Lisp macros)?


As Jens pointed out, syntax-rules isn't designed to do this. Here's one way
to do it with syntax-case (in case you're willing to consider
implementations which support that):

(define-syntax defstr
(lambda (stx)
(syntax-case stx ()
((defstr name field ...)
(let ((len (length #'(field ...))))
#`(define name #,len))))))

[Note that PLT requires (syntax->list #'(field ...)) above]. This is done
somewhat defmacro-style, with the main difference being explained by
syntax-case's use of a special datatype for syntax, which requires the use
of syntax-oriented equivalents of the usual quoting and unquoting operators,
prefixed by #.

Another difference between the above and a defmacro version is that 'name'
is not unquoted in the final syntax template. In contrast, a defmacro
version would typically use `(define ,name ,len). But syntax-case allows
you to eliminate unquoting if you want to, e.g.:

(define-syntax defstr
(lambda (stx)
(syntax-case stx ()
((defstr name field ...)
(let ((len (length (syntax-object->datum #'(field ...)))))
(with-syntax ((len len))
#'(define name len)))))))

This simply introduces 'len' as a syntax variable which can then be used in
syntax templates without unquoting. It's not particularly beneficial in
such a small example, but in more complex cases it can be very useful, since
it more or less eliminates the class of errors which occurs due to
forgetting to unquote something.

Anton


Ulrich Hobelmann

2005-02-20, 8:58 pm

Anton van Straaten wrote:
> Ulrich Hobelmann wrote:
>
>
>
> As Jens pointed out, syntax-rules isn't designed to do this. Here's one way
> to do it with syntax-case (in case you're willing to consider
> implementations which support that):


I might think about that. BTW, are there any plans to make a SRFI out
of syntax-case, since it seems to be a standardized and popular
extension to R5RS Scheme? This might allow broader support (because of
broader attention) from Scheme implementations.

I guess then that syntax-rules also can't create identifiers? What I'd
like to do is to use a macro that creates an object to create
accessor-functions:

(defclass foo a b)

=> (define (foo-a foo) ...)

The foo-a would have to be created somehow, but define only allows a
symbol as its first argument (and not any nice expression).
Anton van Straaten

2005-02-21, 9:00 pm

Ulrich Hobelmann wrote:
> I might think about that. BTW, are there any plans to make a SRFI out
> of syntax-case, since it seems to be a standardized and popular
> extension to R5RS Scheme? This might allow broader support (because
> of broader attention) from Scheme implementations.


I don't think the lack of a SRFI is inhibiting support for syntax-case. A
portable implementation exists (intended for implementors), which acts as a
reference implementation. Versions are available in Chicken, Gambit, Guile,
JScheme, PLT, SCM and SISC at least.

> I guess then that syntax-rules also can't create identifiers?


Practically speaking, no.

> What I'd like to do is to use a macro that creates an object
> to create accessor-functions:
>
> (defclass foo a b)
>
> => (define (foo-a foo) ...)
>
> The foo-a would have to be created somehow, but define only allows
> a symbol as its first argument (and not any nice expression).


You need a more expressive macro system. Most systems other than
syntax-rules would work.

Anton


oleg@pobox.com

2005-02-21, 9:00 pm


Ulrich Hobelmann wrote:
> I guess then that syntax-rules also can't create identifiers? What

I'd
> like to do is to use a macro that creates an object to create
> accessor-functions:
>
> (defclass foo a b)
>
> => (define (foo-a foo) ...)
>
> The foo-a would have to be created somehow, but define only allows a
> symbol as its first argument (and not any nice expression).


Perhaps you might be interested in the page
http://pobox.com/~oleg/ftp/Scheme/define-struct.html
``How to build `identifiers' with syntax-rules''

which uses precisely the example of implementing the macro
define-struct and ``generating'' the names of accessors and
setters.

oleg@pobox.com

2005-02-21, 9:00 pm


Ulrich Hobelmann wrote:
> I guess then that syntax-rules also can't create identifiers? What

I'd
> like to do is to use a macro that creates an object to create
> accessor-functions:
>
> (defclass foo a b)
>
> => (define (foo-a foo) ...)
>
> The foo-a would have to be created somehow, but define only allows a
> symbol as its first argument (and not any nice expression).


Perhaps you might be interested in the page
http://pobox.com/~oleg/ftp/Scheme/define-struct.html
``How to build `identifiers' with syntax-rules''

which uses precisely the example of implementing the macro
define-struct and ``generating'' the names of accessors and
setters.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com