为什么Julia程序员需要在宏前加上“@”符号?

8
每当我看到像@assert@time这样使用Julia宏的时候,我总是在想为什么需要在语法上区分宏和其他函数。当我使用@符号时应该考虑什么?对我来说,它会给这个本来非常好的语言(从语法角度来说)增加噪音和干扰。
我的意思是,对我来说,“@”有一个引用的含义,即像域名或地址这样的位置。在位置上,@对于宏除了它是不同的编译步骤之外没有其他含义。

6
你应该思考:“嘿,我可以尝试使用macroexpand或阅读任何相关文档来弄清楚这个宏展开成什么,否则我就不知道这段代码会做什么!”这是一种明确的设计决策,为了让用户意识到发生了不同的事情,给予宏调用特殊语法。我认为“@”符号在特定含义上并没有更多的含义,除了这个符号恰好是可用的(如果你认为这个用法很困惑,请查看PEP 465)。 - Isaiah Norton
1
谢谢,查阅维基百科文章后,“@”符号作为时间前置词的语义非常贴切! - implicit_knowledge
3个回答

18

@应被视为一个警告符号,表明语言的常规规则可能不适用。例如,函数调用。

f(x)

将不会修改调用环境中变量 x 的值,但是宏调用会。

@mymacro x

(或者对于那件事来说@mymacro f(x)也可能很好)。

另一个原因是,Julia中的宏不像C语言中的文本替换一样,而是在抽象语法树中进行替换(这更加强大,避免了文本替换宏所臭名昭著的意外后果)。

Julia中的宏有特殊的语法,由于它们在解析时间之后扩展,所以解析器还需要一种明确的方式来识别它们(而不知道在当前范围内定义了哪些宏)。

在大多数编程语言的设计中,ASCII字符是一种珍贵的资源,Julia也不例外。我猜选择@主要是因为它没有被用于更重要的事情,并且它很突出。


谢谢,明确区分编译阶段是合理的。 - implicit_knowledge

4
符号总是需要在它们被使用的上下文中进行解释。在不同的上下文中具有多个符号含义并不是新鲜事,而且可能永远都不会消失。例如,在 C 程序中没有人期望 #include 可以在 Twitter 上走红。 Julia's Documentation 中的一篇文章Hold up: why macros? 很好地解释了编写和/或使用宏时应该记住的一些事情。
以下是一些摘录:

宏是必需的,因为它们在解析代码时执行,所以,宏允许程序员在运行整个程序之前生成和包含自定义代码片段。

...

重要的是要强调,宏将其参数作为表达式、字面量或符号进行接收。

如果用一个表达式调用宏,则它会得到整个表达式,而不仅仅是结果。
...

在书写语法的位置,宏调用被扩展为其返回的结果。

请注意:本文中的 HTML 标签已保留。

2

实际上,@符号的语义非常契合它本身的含义。

如果我们查看维基百科中“@符号”的条目,我们会发现它经常被用作代替介词“at”(是的,它甚至读作“at”)。而介词“at”被用来表示一个空间或时间关系。

因此,我们可以使用@符号作为介词“at”的缩写,以引用空间关系,例如位置@tony's bar,@france等,某些内存位置@0x50FA2C(例如用于指针/地址),消息接收者(@user0851在Twitter和其他论坛中使用等),但也可以表示时间关系,例如@05:00 am,@midnight,@compile_time或@parse_time

由于宏在解析时处理(就在这里),这与在运行时评估的其他代码完全不同(是的,在其中有许多不同的阶段,但这不是本文的重点)。 为了明确地将注意力引导到后面的代码片段是在解析时处理的!而不是在运行时处理,我们使用@。

对我来说,这个解释很好地契合了语言。

感谢大家@ ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接