Author: larry
Date: Fri Feb 24 13:06:51 2006
New Revision: 7856

Modified:
   doc/trunk/design/syn/S06.pod
Log:
Revamped quasiquoting for visual, nestable, non-code-interfering unquoting.


Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod        (original)
+++ doc/trunk/design/syn/S06.pod        Fri Feb 24 13:06:51 2006
@@ -13,9 +13,9 @@ Allison Randal <[EMAIL PROTECTED]>
 
   Maintainer: Larry Wall <[EMAIL PROTECTED]>
   Date: 21 Mar 2003
-  Last Modified: 23 Feb 2006
+  Last Modified: 24 Feb 2006
   Number: 6
-  Version: 17
+  Version: 18
 
 
 This document summarizes Apocalypse 6, which covers subroutines and the
@@ -1862,13 +1862,16 @@ original language and know which parts o
 from which parts of the user's view of the program.
 
 In aid of returning syntax tree, Perl provides a "quasiquoting"
-mechanism using the keyword "CODE", followed by a block intended to
+mechanism using the quote C<q:code>, followed by a block intended to
 represent an AST:
 
-    return CODE { say $a };
+    return q:code { say $a };
 
-[Conjecture: Other keywords are possible if we have more than one
-AST type.]
+Modifiers to the C<:code> adverb can modify the operation:
+
+    :ast(MyAst)                # Default :ast(AST)
+    :lang(Ruby)                # Default :lang($?PARSER)
+    :unquote<[: :]>    # Default "triple rule"
 
 Within a quasiquote, variable and function names resolve first of
 all according to the lexical scope of the macro definition, and if
@@ -1876,41 +1879,57 @@ unrecognized in that scope, are assumed 
 of the macro call each time it is called.  If they cannot be bound
 from the scope of the macro call, a compile-time exception is thrown.
 
-Variables that resolve from the lexical scope of the macro definition
-will be inserted appropriately depending on the type of the variable,
-which may be either a syntax tree or a string.  (Again, syntax tree
-is preferred.)  The case is similar to that of a macro called from
-within the quasiquote, insofar as reparsing only happens with the
-string version of interpolation, except that such a reparse happens
-at macro call time rather than macro definition time, so its result
-cannot change the parser's expectations about what follows the
-interpolated variable.
+Bare AST variables (such as the arguments to the macro) may not be
+spliced directly into a quasiquote because they would be taken as
+normal bindings.  Likewise, program text strings to be inserted need
+to be specially marked or they will be bound normally.  To insert a
+"unquoted" expression of either type within a quasiquote, use the
+quasiquote delimiter tripled, typically a bracketing quote of some sort:
+
+    return q:code { say $a + {{{ $ast }}} }
+    return q:code [ say $a + [[[ $ast ]]] ]
+    return q:code < say $a + <<< $ast >>> >
+    return q:code ( say $a + ((( $ast ))) )
+
+(Note to implementors: this must not be implemented by finding
+the final closing delimiter and preprocessing, or we'll violate our
+one-pass parsing rule.  Perl 6 parsing rules are parameterized to know
+their closing delimiter, so adding the opening delimiter should not
+be a hardship.  Alternately the opening delimiter can be deduced from
+the closing delimiter.  Writing a rule that looks for three opening
+delimiters in a row should not be a problem.  It has to be a special
+grammar rule, though, not a fixed token, since we need to be able to
+nest code blocks with different delimiters.  Likewise when parsing the
+inner expression, the inner parser rule is parameterized to know that
+C<}}}> or whatever is its closing delimiter.)
+
+The delimiters don't have to be bracketing quotes, but the following
+is probably to be construed as Bad Style:
+
+    return q:code / say $a + /// $ast /// /
+
+Dequoted expressions are inserted appropriately depending on the
+type of the variable, which may be either a syntax tree or a string.
+(Again, syntax tree is preferred.)  The case is similar to that of a
+macro called from within the quasiquote, insofar as reparsing only
+happens with the string version of interpolation, except that such
+a reparse happens at macro call time rather than macro definition
+time, so its result cannot change the parser's expectations about
+what follows the interpolated variable.
 
 Hence, while the quasiquote itself is being parsed, the syntactic
-interpolation of a variable into the quasiquote always results in
-the expectation of an operator following the variable.  (You must
-use a call to a submacro if you want to expect something else.)
-Of course, the macro definition as a whole can expect whatever it
-likes afterwards, according to its syntactic category.  (Generally,
-a term expects a following postfix or infix operator, and an operator
-expects a following term or prefix operator.)
-
-In case of name ambiguity, prefix with C<COMPILING::> to indicate a
-name in the compiling scope, and anything else (such as C<OUTER::>)
-to indicate a name in the macro definition's scope, since that's the
-default.  In particular, any variable declared within the quasiquote
-block is assumed to scope to the quasiquote; to scope the declaration
-to the macro call's scope, you must say
-
-    my COMPILING::<$foo> = 123;
-    env COMPILING::<@bar> = ();
-    our COMPILING::<%baz>;
-
-or some such if you wish to force the compiler to install the variable
-into the symbol table being constructed by the macro call.
-
-[Conjecture: Due to these dwimmy scoping rules, there is no need of
-a special "unquote" construct as in Scheme et al.]
+interpolation of a unquoted expression into the quasiquote always
+results in the expectation of an operator following the variable.
+(You must use a call to a submacro if you want to expect something
+else.)  Of course, the macro definition as a whole can expect
+whatever it likes afterwards, according to its syntactic category.
+(Generally, a term expects a following postfix or infix operator,
+and an operator expects a following term or prefix operator.)
+
+A quasiquote is not a block (even if the delimiters are curlies),
+so any declaration of a variable is taken to be part of the block
+surrounding the macro call location.  Add your own {...} if you want
+a block to surround your declarations.
 
 =head1 Other matters
 

Reply via email to