[t/spec] Add tricky tests (which pass after latest Rakudo patch), unfudge old simple...
[pugs.git] / t / unspecced / macro_code_test.t
blob6dbffbdd7c3413636567d31feda818692c53791c
1 use v6;
2 use Test;
5 plan 3;
6 # Avoiding accidental multiple execution 
7 # as occurs in C's defines and lisp macros
8 # This can also ensure a correct order of evaluation
10 # This needs to be decided
11 # is CST (Concrete)
12 # is Thunk
13 # is Proxy
14 # is Reduced
15 # is Bound
16 # is Once
17 # is Evaluated
18 # is EvaluatedOnce
19 # is Eager
20 macro max ($x is CST, $y is CST) {
21     return quasi { ($x > $y) ?? $x !! $y };
24 # Alternatively, the default could be eval once and the special name
25 # is for the CallByName version
27 my ($x, $y) = (1,2);
29 my $got = max($x++, $y++);
31 # say qc'$x = {$x} $y = {$y}';
33 is($x,   2, '$x incremented once', :todo<unspecced>);
34 is($y,   3, '$x incremented once', :todo<unspecced>);
35 is($got, 3, '$got incremented max', :todo<unspecced>);
37 =begin pod
39 =head1 quasi & AST splicing options
41 =head2 Splicing Problem
43 The contents of quasi blocks need to be able to refer to values
44 as any other closure does, but also define graft points for
45 other asts.
47 =head2 Solution Space
49 First principle, adding quasi before a block doesn't change things
50   - it's still a closure
51   - if you mention $var it means the $var in the surrounding lexical scope
52     (mentioning new vars may bind at the macro use)
53   - subs continue to be bound to the local definitions
54   - macros continue to be expanded at parse time (quasi parse time)
56 Second principle, to do something special, say something special.
58 Differences: possible variable/sub not defined errors may bind at macro uses
59 or are delayed.
61 macro parameters may be ASTs, strings, or possibly a singly-evaluated-ASTs,
62 the point is to wrap or warp them into the returned AST|string.
63 We want an easy way to splice the input AST into the output AST
64 The output AST is usually a quasi block somehow using the macro arg asts:
66   quasi { my $x; $x; $input_ast; $captured_var; $var_at_call }
68 =head2 Some Suggested Solutions
70  * Roles, anything that does QuasiQuote is spliced including ASTs,
71    ThunkishASTS and certain strings
72    literal($ast) macro to talk about an ast as a value
74  * signature such as quasi ($ast) { $var; $ast }
75    (idea--: duplicates macro's param list, violates sig -> application w/ args 
76     expectation with subs)
78  * twigil used for interpolating AST/strings
80  * escape meta-syntax (lisp's solution)  
81     quasi { say "Exp (\qq[~$package]) = ", \qq[$package] }
83  * set of escape macros which only apply in quasi blocks glue($ast)
85 More complex restructuring of the input AST would require walking
86 the AST (or munging the string).  Nothing spec'd for that yet.
87 We would likw to ensure only valid ASTs can be produced.
89 Perl's rules may be able to scan the tree with L<S05/"Matching against non-strings">
90 and just s:g/// to produce the output ast.  
92 If a tree grammar tool reaches the Perl 6 user space then that can be used
94 =head2 Current Solution
96 quasi { } is the quoter and {{{ }}} is the default antiquote
97 (the rule is actually the delimiter repeated thrice).
98 The use of {{{ ... }}} in a quasi is just like an inline macro.
99 Pretending that the body of you program is within a quasi{ }
100 then {{{ }}} can be used for inline macros, compile time
101 generation of ASTs which are spliced immediately.
103 =head1 Recursive Macros
105 We started thinking about these, but then realized we'd need to
106 know how they work, so we started thinking about these, ...
108 These are banned in C but permitted in Lisp (and a source of
109 infinite loops during compilation).  We could adopt either method
110 or try to reduce the likely pain.  Lisp allows a recursive expander
111 function, but not a recursive expansion.
113 It seems impossible to parse beyond a recursive macro call,
114 so we can ask Turing's oracle or give up.
116 One remaining possibility to add the macro expansion to a todo list that
117 is run after the macro definition is completed.  The effects of the
118 macro may then be different from the non-recursive case.
119 It is different to a mere sub call however, as it happens immediately
120 after the definition.
122 Finally, a recursive call could merely be a subroutine call, allowing
123 recursion at runtime (which is compile time as far as the macro's caller
124 is concerned).  This is perhaps close to C++ template expansion games.
126 Recursive macros seem to be an unneeded feature, ast's equivalent
127 to those from a recursive macro can be contructed using normal runtime tools, 
128 including subroutine recursion.
130 =head2 Run Defined Macros Only
132 Macros are only macros once
135 =head1 Quoting Declarations
137 Can declarations and pragmas be quoted?
138 $Larry "I don't see why not"
140  quasi { sub x { ... }; macro y { ... }; use force; }
142 The AST needs to be rescanned anyway, so perform the appropriate
143 actions at that time in the correct scope.
145 =end pod
146 # vim: syntax=perl6: