<div><span style="color: rgb(160, 160, 168); ">On Saturday 31 March 2012 at 13:23, Mikael wrote:</span></div>
                <blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;">
                    <span><div><div>Hi Per,<br><br>What's |alias|' scope - just to doublecheck I got your point, is it, that it expands the passed identifier to the fully qualified name form (i.e. the complete and non-overlappable form), of the identifier with that name that is defined the most closely upwards in the lexical scope from the point where |alias| is used?<br></div></div></span></blockquote><div>Yeah.. I think that's right. |alias| uses the same scope as where the form is written.</div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div>

I suppose that's how it is. So the following<br><br><span style="font-family:courier new,monospace">(define a 0)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(alias a)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">(define a -1)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(alias a)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">(let ((a 0))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">   (define-macro (somename) (alias a))</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">
   (define a 1)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">   (define-macro (somename) (alias a) (let ((a 2)) (alias a))))</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">   (define a 3)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">   (define-macro (b) (alias a))</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">

   (let ((a 4))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">      (alias a)<br>      </span><span style="font-family:courier new,monospace">(b)</span><span style="font-family:courier new,monospace">)))</span><br>

<br>would expand to (a functional equivalent of)<br><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define 0#a 0)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">0#a</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">(define 1#a -1)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">1#a</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">(let ((2#a 0))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">
   (define-macro (somename) 2#a)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">

   (define 3#a 1)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">
   (define-macro (somename) 3#a (let ((4#a 2)) 4#a)))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">
   (define 5#a 3)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">
   (define-macro (somename) 5#a)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">


   (let ((6#a 4))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">
      6#a<br>      5#a)))</span><br style="font-family:courier new,monospace"><br>?<br></div></div></span></blockquote><div>Almost, but not quite. Duplicate definitions on the top level in the REPL should overwrite each other, not create separate bindings. So if you're in the "mod#" namespace, both top level definitions of a should expand into (define mod#a …). This is consistent with Gambit's current behavior.</div><div><br></div><div>Multiple defines of the same variable name within a scope, like 3#a and 5#a in your example, is not legal Scheme. If Black Hole allows this syntax, it's a bug in Black Hole. Gambit rejects the code with a "Duplicate definition of a variable" message.</div><div><br></div><div>Other than that, yes, that's how it should work.</div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div>Are there any key aspects of |alias|' renaming function that the above example does not illustrate, if so which?<br></div></div></span></blockquote><div>No. The rules are really simple. The cases that you bring up that are non-obvious are not legal Scheme, so they don't need to be considered.</div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div>And thus, we get a mechanism for syntax-rules-style hygiene i.e.<br>

<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">; (Here neither cons nor error are overlapped, but Gambit's defaults)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">(define-syntax real-cons (syntax-rules () ((real-cons a b) (cons a b))))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define cons error)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">(</span><span style="font-family:courier new,monospace">real-cons</span><span style="font-family:courier new,monospace"> 1 2)</span><br style="font-family:courier new,monospace">

<br>can as well be written<br><br><span style="font-family:courier new,monospace">; (Here neither cons nor error are overlapped, but Gambit's defaults)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace"></span><span style="font-family:courier new,monospace">(define-macro (real-cons a b) `(,(alias cons) ,a ,b))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define cons error)</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">
(</span><span style="font-family:courier new,monospace">real-cons</span><span style="font-family:courier new,monospace"> 1 2)</span><br style="font-family:courier new,monospace">
<br>, both expanding to (a functional equivalent of)<br><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"></span><span style="font-family:courier new,monospace">(define 2#cons #error) ; #error as in, Gambit's standard |error|</span><br style="font-family:courier new,monospace">



<span style="font-family:courier new,monospace">(#cons 1 2) </span><span style="font-family:courier new,monospace">; #cons as in, Gambit's standard |cons|</span><br style="font-family:courier new,monospace"><br>Correct?<br></div></div></span></blockquote><div>Yes, both the syntax-rules macro and the define-macro macro would be equivalent (possibly except for error handling and source code location information).</div><div><br></div><div>Your statement about this being syntax-rules-style hygiene isn't really correct, though: One of the main points with syntax-rules is that you don't need gensym. With this macro system, you still need to explicitly use gensym.</div><div><br></div><div>The reason for this is that you can't use |alias| when you bind names:</div><div><br></div><div><font face="'Courier New'">(define-macro (mac code)</font></div><div><font face="'Courier New'">  `(,(alias let) ((,(alias a) 'a)) ,code ,(alias a)))</font></div><div><br></div><div>The code snippet above isn't necessarily hygienic. You need gensyms for hiding any names that macros bind. And AFAIK there is no way of doing that automatically with this system: For that you need to introduce a new identifier data type, like syntactic closures, explicit renaming and syntax-case do.</div><div><br></div><div>Per</div><div><br></div>