<!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>&nbsp;</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.&nbsp;To solve these shortcomings&nbsp;requires runtime&nbsp;registers too. 
They&nbsp;cannot be solved in the expansion phase)</FONT></DIV>
<DIV><FONT face="Courier New"></FONT>&nbsp;</DIV>
<DIV>(((((lambda(x)((((((((x x)x)x)x)x)x)x)x))<BR>&nbsp;&nbsp;&nbsp; 
(lambda(x)(lambda(y)(x(x y)))))<BR>&nbsp;&nbsp; (lambda(x)(x)x))<BR>&nbsp; 
(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>&gt; 
  Inspired by the dot notation of Jens Axel Søgaard I tried to eliminate the 
  <BR>&gt; need for define-accessor. See enclosure. However, I can't get rid of 
  the error <BR>&gt; reported at the end of my trial, reading:<BR>&gt; "compile: 
  bad syntax; reference to top-level identifier is not allowed, <BR>&gt; because 
  no #%top syntax transformer is bound in: acc85"<BR><BR>The problem starts 
  here:<BR><BR>&nbsp;(define-syntax (define-struct-type stx)<BR>&nbsp; 
  (syntax-case stx ()<BR>&nbsp;&nbsp; ....<BR>&nbsp;&nbsp; ((define-struct-type 
  (descr constr pred super) (field ...) inspector)<BR>&nbsp;&nbsp;&nbsp; 
  (let-values (((acc mut) (apply values (generate-temporaries #'(acc 
  mut)))))<BR>&nbsp;&nbsp;&nbsp;&nbsp; (register-transformer-builder #'constr 
  #'(field ...) acc mut)<BR>&nbsp;&nbsp; #`(define-values (descr constr pred 
  #,acc #,mut)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....)))))<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>&nbsp;(define-syntax (define-struct-type 
  stx)<BR>&nbsp; (syntax-case stx ()<BR>&nbsp;&nbsp; ....<BR>&nbsp;&nbsp; 
  ((define-struct-type (descr constr pred super) (field ...) 
  inspector)<BR>&nbsp;&nbsp;&nbsp; (let-values (((acc mut) (apply values 
  (generate-temporaries #'(acc mut)))))<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
  #`(begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (begin-for-syntax<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (register-transformer-builder #'constr #'(field ...) #'#,acc 
  #'#,mut))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (define-values 
  (descr constr pred #,acc 
  #,mut)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ....))))))<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>&nbsp; <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>&nbsp;(module m mzscheme<BR>&nbsp;&nbsp; (require 
  dot)<BR>&nbsp;&nbsp; (define-struct-type d c p (x y z) 
  (make-inspector))<BR>&nbsp;&nbsp; (provide d c p))<BR><BR>&nbsp;(module n 
  mzscheme<BR>&nbsp;&nbsp; (require dot m)<BR>&nbsp;&nbsp; (define-struct-var s 
  (c 1 2 add1))<BR>&nbsp;&nbsp; (printf "~s\n" s.x))<BR><BR>then you 
  get<BR><BR>&nbsp;compile: access from an uncertified context to unexported 
  variable<BR>&nbsp;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>&nbsp;(define-syntax 
  (define-struct-type stx)<BR>&nbsp; (syntax-case stx ()<BR>&nbsp;&nbsp; 
  ....<BR>&nbsp;&nbsp; ((define-struct-type (descr constr pred super) (field 
  ...) inspector)<BR>&nbsp;&nbsp;&nbsp; (let-values (((acc mut) (apply values 
  (generate-temporaries #'(acc mut)))))<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
  #`(begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (begin-for-syntax<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (let ([cert 
  (syntax-local-certifier)])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (register-transformer-builder #'constr #'(field ...) 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (cert 
  #'#,acc)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (cert #'#,mut))))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (define-values (descr constr pred #,acc 
  #,mut)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ....))))))<BR><BR>Revised code and example 
enclosed.<BR><BR>Matthew<BR></BLOCKQUOTE></BODY></HTML>