宏不允许定义词法变量

jjm*_*elo 7 macros perl6

此代码使用(实验)宏:

use experimental :macros; 
macro new-var() { 
  quasi { 
    my $a = 42
  }
};
new-var; 
say $a
Run Code Online (Sandbox Code Playgroud)

失败Variable '$a' is not declared,虽然宏没有错误通过.如果这是一个正确的宏声明,它会做什么?如果不是,有没有办法从宏中定义新变量?

Jon*_*ton 8

moritz的答案对于宏的状态是正确的,尽管根据我对007中所做工作的了解,我认为即使使用Perl 6宏的工作实现,编写的程序也是正确的.

Perl 6宏本质上不是文本的(C宏是文本的宏).A quasi是一个引用构造,就像我们有字符串和正则表达式的引号一样,除了引用Perl 6代码,将其表示为AST-ish.(我曾经说它会产生AST,但是我们已经意识到,如果一个中缀是在一个准内部内插的,那么它会带来一个优先级和相关性,而我们实际上无法形成正确的树.表达直到插值后.)

有一个"卫生"的宏观概念,默认情况下,宏体中声明的符号不应泄漏到应用宏的位置,因为它们可能只是实现细节.人们必须明确要求将符号放入应用宏的编译上下文中.所以我希望程序看起来像这样:

macro new-var() { 
    quasi { 
        my COMPILING::<$a> = 42
    }
};
new-var; 
say $a
Run Code Online (Sandbox Code Playgroud)

请注意,这在今天的Rakudo中不起作用,尽管您可能会发现它可以在007中使用.


mor*_*itz 7

这可能不是您正在寻找的答案,但Rakudo中的宏目前真的被打破了.在这个时间点,我甚至不记得它是否应该工作,或者它是否是Rakudo的一个错误 - 它几乎不值得它搞清楚,因为大多数宏观事物根本不起作用.

这就是为什么CarlMäsak创建007以在Rakudo核心之外尝试宏设计,目标是最终将经验教训带回Rakudo和Perl 6语言设计.