<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META content="MSHTML 6.00.6000.16414" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face="Courier New">Hi Matthew</FONT></DIV>
<DIV><FONT face="Courier New">Thanks, that 's quick and clear. It took you less
time for you to answer me than for me to read your answer. Thanks, Jos Koot.
</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">(Warning to others: module dot should be
discouraged because it has some nasty shortcomings I am still working
on. To solve these shortcomings requires runtime registers too.
They cannot be solved in the expansion phase)</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV>(((((lambda(x)((((((((x x)x)x)x)x)x)x)x))<BR>
(lambda(x)(lambda(y)(x(x y)))))<BR> (lambda(x)(x)x))<BR>
(lambda()(printf "Greetings, Jos~n"))))</DIV>
<BLOCKQUOTE
style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV style="FONT: 10pt arial">----- Original Message ----- </DIV>
<DIV
style="BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: black"><B>From:</B>
<A title=mflatt@cs.utah.edu href="mailto:mflatt@cs.utah.edu">Matthew Flatt</A>
</DIV>
<DIV style="FONT: 10pt arial"><B>To:</B> <A title=jos.koot@telefonica.net
href="mailto:jos.koot@telefonica.net">jos koot</A> </DIV>
<DIV style="FONT: 10pt arial"><B>Cc:</B> <A title=plt-scheme@list.cs.brown.edu
href="mailto:plt-scheme@list.cs.brown.edu">plt-scheme@list.cs.brown.edu</A>
</DIV>
<DIV style="FONT: 10pt arial"><B>Sent:</B> Monday, March 19, 2007 7:56
AM</DIV>
<DIV style="FONT: 10pt arial"><B>Subject:</B> Re: [plt-scheme] Dot-notation
for structure field access</DIV>
<DIV><BR></DIV>At Sun, 11 Mar 2007 12:49:17 +0100, "jos koot" wrote:<BR>>
Inspired by the dot notation of Jens Axel Søgaard I tried to eliminate the
<BR>> need for define-accessor. See enclosure. However, I can't get rid of
the error <BR>> reported at the end of my trial, reading:<BR>> "compile:
bad syntax; reference to top-level identifier is not allowed, <BR>> because
no #%top syntax transformer is bound in: acc85"<BR><BR>The problem starts
here:<BR><BR> (define-syntax (define-struct-type stx)<BR>
(syntax-case stx ()<BR> ....<BR> ((define-struct-type
(descr constr pred super) (field ...) inspector)<BR>
(let-values (((acc mut) (apply values (generate-temporaries #'(acc
mut)))))<BR> (register-transformer-builder #'constr
#'(field ...) acc mut)<BR> #`(define-values (descr constr pred
#,acc #,mut)<BR> ....)))))<BR><BR>The call
to `register-transformer-builder' is a side effect that<BR>happens while the
macro is expanded. After a `define-struct-type' form<BR>is expanded --- say,
when compiling a module --- the side-effect won't<BR>happen anymore. In
particular, the side effect won't happen if you<BR>(next week, on a different
machine) load the compiled form of module<BR>whose source contains the
`define-struct-type' declaration.<BR><BR>Well, the error you see is only
indirectly related to the problem,<BR>which is partly why it's difficult to
track down. The problem is that<BR>the registration uses `acc' and `mut'
identifiers before any such<BR>bindings exist, and that leads to the bad
reference.<BR><BR>The solution to both problems is the same, and it's simple
to write<BR>down:<BR><BR> (define-syntax (define-struct-type
stx)<BR> (syntax-case stx ()<BR> ....<BR>
((define-struct-type (descr constr pred super) (field ...)
inspector)<BR> (let-values (((acc mut) (apply values
(generate-temporaries #'(acc mut)))))<BR>
#`(begin<BR>
(begin-for-syntax<BR>
(register-transformer-builder #'constr #'(field ...) #'#,acc
#'#,mut))<BR> (define-values
(descr constr pred #,acc
#,mut)<BR>
....))))))<BR><BR>All I've done is move the `register-transformer-builder'
call into the<BR>result of the macro, so that it's a side-effect wrapped
by<BR>`begin-for-syntax'. Since it's part of the result expansion, the
side<BR>effect happens each time the expanded (or compiled) expression
is<BR>loaded.<BR><BR>Moreover, `acc' and `mut are now in the same binding
context as the<BR>`define-values' form, so they get bound in the way that you
want.<BR><BR><BR>The general rule is: Don't put any side-effects in a macro
expansion.<BR>If you must have side effects at compile time, they should be
in<BR>`begin-for-syntax'.<BR><BR><BR>See also <BR> <A
href="http://www.cs.utah.edu/plt/publications/macromod.pdf">http://www.cs.utah.edu/plt/publications/macromod.pdf</A><BR>which
may make more sense now that you've hit the problem that it<BR>describes.
:)<BR><BR><BR>Unfortunately, there's a small catch, which I think is almost
certainly<BR>related to your later question about `syntax-recertify'. If you
try<BR><BR> (module m mzscheme<BR> (require
dot)<BR> (define-struct-type d c p (x y z)
(make-inspector))<BR> (provide d c p))<BR><BR> (module n
mzscheme<BR> (require dot m)<BR> (define-struct-var s
(c 1 2 add1))<BR> (printf "~s\n" s.x))<BR><BR>then you
get<BR><BR> compile: access from an uncertified context to unexported
variable<BR> from module: m at: acc1 in: acc1.1<BR><BR>Even though
there's no `local-expand' in the macro implementation,<BR>there is a kind of
manual expansion that happens when looking up a<BR>binding via
`register-lookup'. That manual lookup must be accompanied<BR>by manual
management of certificates (though not through
using<BR>`syntax-recertify').<BR><BR>So, explicitly certify the referencing
identifiers before you record<BR>them:<BR><BR> (define-syntax
(define-struct-type stx)<BR> (syntax-case stx ()<BR>
....<BR> ((define-struct-type (descr constr pred super) (field
...) inspector)<BR> (let-values (((acc mut) (apply values
(generate-temporaries #'(acc mut)))))<BR>
#`(begin<BR>
(begin-for-syntax<BR>
(let ([cert
(syntax-local-certifier)])<BR>
(register-transformer-builder #'constr #'(field ...)
<BR>
(cert
#'#,acc)<BR>
(cert #'#,mut))))<BR>
(define-values (descr constr pred #,acc
#,mut)<BR>
....))))))<BR><BR>Revised code and example
enclosed.<BR><BR>Matthew<BR></BLOCKQUOTE></BODY></HTML>