[racket] a syntax-case question

From: Marco Maggi (marco.maggi-ipsu at poste.it)
Date: Wed Sep 28 02:10:19 EDT 2011

Jon Stenerson wrote:

> I'm trying to understand what this is supposed to do:

> (define (parse stx)
>   (syntax-case stx ()
>     [(_ p ...) #'(p ...)]))

> (display (parse #'(1 2 3)))

Are  you  interested  only  in the  difference  between  the
results  in  different  languages  or  also  in  the  actual
operations performed by SYNTAX-CASE?

> If I run  this in DrRacket with first  line #lang racket I
> get a  syntax object  containing a list:  #<syntax:7:17 (2
> 3)>

  If  I  run  the code  as  a  script  from a  terminal  (in
GNU+Linux) I get:

{#<syntax:/home/marco/var/tmp/proof.sps:11:21 2>
 #<syntax:/home/marco/var/tmp/proof.sps:11:23 3>}

> Is this a legitimate  difference between two languages? Or
> is one of them right and the other wrong?

  Both representations are valid.   When the return value is
a single syntax object holding a list, it is called "wrapped
syntax object";  when the return  value is a list  of syntax
objects  it is  called "unwrapped  syntax object"  or simply
"syntax object".[1]

  We can think of a  wrapped syntax object as an instance of
the record type SYNTAX-OBJECT,  which is usually not exposed
in the public API of a Scheme language implementation, while
an unwrapped  syntax object is  a compound value  holding at
least one  instance of the record type  SYNTAX-OBJECT and no
Scheme symbols outside of SYNTAX-OBJECT records.

  It is always possible to unwrap a wrapped syntax object to
produce  an  (almost)   equivalent  fully  unwrapped  syntax
object.  In general, the two representations:

   #<syntax:(2 3)>
   (#<syntax:2> #<syntax:3>)

hold the same informations with respect to what is needed to
produce the output  form of a macro, but  the wrapped syntax
object may hold  "better" meta-informations, like the source
location of the list it holds.

  Notice that in this  specific case the syntax object holds
only number values, so it would have been perfectly legal to
just return a plain list:

   (2 3)

because, for the purpose of completing the macro expansions,
no lexical informations need to be attached to datum values;
strictly    speaking,   only   identifiers    need   lexical

  Stripping the context from a  list of numbers has at least
two effects:

* Meta-informations (like source code location) are lost.

* The stripped value cannot be used as first argument to the
  function DATUM->SYNTAX, which is sometimes useful.  Racket
  allows this in non-R6RS languages, R6RS requires the first
  argument to be an identifier.

  Wrapped  syntax  objects  can  sometimes  be  more  memory
efficient  and  they can  sometimes  be  handled  in a  more
efficient way (requiring less  operations to be dealt with);
but while  the expander completes its work:  sooner or later
it  will fully  unwrap all  the syntax  objects it  needs to
produce an output form.

  You  may  be  interested  in  reading my  dirty  and  ugly
introduction for beginner users of SYNTAX-CASE[2].


[1] <http://marcomaggi.github.com/docs/nausicaa.html/stdlib-syntax_002dcase-objects.html>
[2] <http://marcomaggi.github.com/docs/nausicaa.html/stdlib-syntax_002dcase-intro.html>
Marco Maggi

Posted on the users mailing list.