Whoa, very nice!<br><br>IIUC, you could get rid of syntax-local-eval because you have a sub-macro, so the overall macro puts the content of id-rename inside a sub-macro that is then evaluated.<br>This is also why id is correctly &quot;bound&quot; inside (begin body ...) : after the first expansion, it is not really body ..., but the full expression containing id.<br>

It is definitely better.<br>
<br>Also, the first let () is not really needed I guess.<br><br>Thank you very much.<br>Laurent<br><br><div class="gmail_quote">On Mon, Apr 18, 2011 at 20:42, Jon Rafkind <span dir="ltr">&lt;<a href="mailto:rafkind@cs.utah.edu" target="_blank">rafkind@cs.utah.edu</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

  
    
  
  <div text="#000000" bgcolor="#ffffff">
    Here is an alternative implementation that makes the example you
    showed at the very bottom of your emails work. I don&#39;t know if its
    &quot;better&quot; but using `syntax-local-eval&#39; looks somewhat dangerous to
    me.<br>
    <br>
    This is mostly straight-forward except that to get the right lexical
    scope for `get-x1&#39; we need to do a little hack (by assuming the
    argument list has at least one thing in it). Of course the original
    macro could enforce such a property as well.<br>
    <br>
    #lang racket<div><br>
    <br>
    (define-syntax (define-syntax-rule/id stx)<br>
      (syntax-case stx ()<br></div>
        [(_ (name arg ...)<br>
            [id id-rename]<br>
            body ...)<br>
         (let ()<br>
         #&#39;(define-syntax (name stx)<br>
             (syntax-case stx ()<br>
               [(_ arg ...)<br>
                ;; we want the defined procedure to have the same
    lexical scope as<br>
                ;; the arguments given to the syntax-rule<br>
                ;; we can&#39;t use #&#39;(arg ...) as the thing to get the
    lexical scope<br>
                ;; because #&#39; will create a new syntax object using the
    lexical<br>
                ;; scope of the code right here. so instead we take out
    the first<br>
                ;; object from the argument list which should have the
    right scope.<br>
                (with-syntax ([id (datum-&gt;syntax (car
    (syntax-&gt;list #&#39;(arg ...)))<br>
                                                 (string-&gt;symbol<br>
                                                   (let ([arg (syntax-e
    #&#39;arg)] ...)<br>
                                                     id-rename))<br>
                                                 (car (syntax-&gt;list
    #&#39;(arg ...))))])<br>
                  #&#39;(begin body ...))]))<br>
           )]))<br>
    <br>
    (define-syntax-rule/id (make-getter xid)<br>
                           [id2 (format &quot;get-~a&quot; xid)]<br>
                           (define (id2) xid))<br>
    <br>
    (define x1 5)<br>
    (make-getter x1)<br>
    (get-x1)<div><div></div><div><br>
    <br>
    <br>
    On 04/18/2011 12:03 PM, Laurent wrote:
    </div></div><blockquote type="cite"><div><div></div><div>Found!<br>
      <br>
      After having read more carefully Eli&#39;s very good post (<a href="http://blog.racket-lang.org/2011/04/writing-syntax-case-macros.html" target="_blank">http://blog.racket-lang.org/2011/04/writing-syntax-case-macros.html</a>),
      it became clearer that the problem was that the context of the
      created identifier was wrong.<br>
      Deconstructing and reconstructing the id syntax object did the
      trick:<br>
      <br>
      (define-syntax (define-syntax-rule/id stx)<br>
        (syntax-case stx ()<br>
          [(_ [id id-gen] body)<br>
           (with-syntax ([id-def (to-syntax <br>
                                  (syntax-e (syntax-local-eval
      #&#39;id-gen))<br>
                                  #:stx stx)])<br>
             #&#39;(splicing-let-syntax ([tmp-form (syntax-rules ()<br>
                                        [(_ id) (begin (displayln &#39;body)<br>
                                                       body)])])<br>
                  (tmp-form id-def))<br>
             )]<br>
          ))<br>
      <br>
      <br>
      Now if anyone knows a better way to implement this or can point
      out problems with this implementation, I&#39;d be glad to know about
      it.<br>
      <br>
      Thanks for listening :)<br>
      Laurent<br>
      <br>
      <br>
      <div class="gmail_quote">On Mon, Apr 18, 2011 at 18:21, Laurent <span dir="ltr">&lt;<a href="mailto:laurent.orseau@gmail.com" target="_blank">laurent.orseau@gmail.com</a>&gt;</span>
        wrote:<br>
        <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
          Dear Racket list,<br>
          <br>
          Once again, I need a little help on a macro definition.<br>
          <br>
          I want to define the following (simplified[1]) macro:<br>
          (define-syntax-rule/id [<i>id id-gen</i>] <i>body</i>)<br>
          <br>
          where id is replaced with the result of id-gen inside body.<br>
          For example:<br>
          (define-syntax-rule/id <br>
            [x #&#39;foo]<br>
            (begin (define x 5)<br>
                   (displayln x)))<br>
          <br>
          is supposed to bind foo to 5 in the top-level at run-time.<br>
          (You can replace #&#39;foo by some complex identifier-making
          expression using format-id.)<br>
          Here is what I have right now, after much trial&amp;error:<br>
          <br>
          #lang racket<br>
          <br>
          (require (for-syntax unstable/syntax)<br>
                   (for-syntax errortrace/errortrace-key)<br>
                   racket/splicing<br>
                   )<br>
          <br>
          (provide (all-defined-out))<br>
          <br>
          ;; Like define-syntax-rule,<br>
          ;; but id is replaced with the result of id-gen in body.<br>
          ;; id-gen is eval&#39;ed at macro-time.<br>
          (define-syntax (define-syntax-rule/id stx)<br>
            (syntax-case stx ()<br>
              [(_ [id id-gen] body)<br>
               (with-syntax ([id-def (syntax-local-eval #&#39;id-gen)])<br>
                 #&#39;(splicing-let-syntax ([tmp-form (syntax-rules ()<br>
                                            [(_ id) (begin (displayln
          &#39;body)<br>
                                                           body)])])<br>
                      (tmp-form id-def))<br>
                 )]<br>
              ))<br>
          <br>
          ;;; TESTS<br>
          <br>
          (define-syntax-rule/id <br>
            [x #&#39;foo]<br>
            (begin (define x 5)<br>
                   (displayln x)<br>
                   (displayln &#39;x)<br>
                   ))<br>
          <br>
          <br>
          It works (foo is bound to 5), except that foo is unknown
          (undefined identifier) after the (begin ...).<br>
          I suspect this is because of syntax-local-eval, but I don&#39;t
          know what to use instead.<br>
          <br>
          There is another intriguing thing:<br>
          if just after (define x 5) we add (provide x), and in another
          file we require the first file, then foo is actually defined
          and can be used normally!<br>
          Why is that and why does this not work when there is no
          (provide x) ? [note that there is a (provide (all-defined
          out)).]<br>
          <br>
          Can someone give me a hint as to what is going on?<br>
          <br>
          I also suspect that using splicing-let-syntax is not the way
          to go, but again I don&#39;t know what to use otherwise, that
          would let me replace id with id-def.<br>
          <br>
          Thank you very much,<br>
          Laurent<br>
          <br>
          <br>
          [1] To explain the name: once finished, this macro will be
          supposed to behave like an augmented version of
          define-syntax-rule but with explicit hygiene breaking:<br>
          <br>
          (define-syntax-rule/id (make-getter id)<br>
            [id2 (format-id #&#39;here &quot;get-~a&quot; id)]<br>
            (define (id2) id))<br>
          <br>
          which, when called on (make-getter foo) would create the
          get-foo function.<br>
        </blockquote>
      </div>
      <br>
      </div></div><pre><fieldset></fieldset>
_________________________________________________
  For list-related administrative tasks:
  <a href="http://lists.racket-lang.org/listinfo/users" target="_blank">http://lists.racket-lang.org/listinfo/users</a></pre>
    </blockquote>
    <br>
  </div>

<br>_________________________________________________<br>
  For list-related administrative tasks:<br>
  <a href="http://lists.racket-lang.org/listinfo/users" target="_blank">http://lists.racket-lang.org/listinfo/users</a><br></blockquote></div><br>