为什么要在Julia中使用宏?

13
我正在阅读有关宏的文档,并在“Hold up: why macros”部分发现了以下内容。使用宏的理由如下:

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

这让我想知道为什么有人希望在整个程序运行之前“生成和包含定制代码片段”。请问有人可以提供相关背景信息以及宏的其他好用例吗?

2
您可以使用宏创建自己的语言结构。我不熟悉Julia,但例如在Clojure中,您可以纯粹使用宏制作自己版本的Python的with块。 - Carcigenicate
1
如果Groovy支持宏,您也可以轻松地使用它们解决这个问题 - Carcigenicate
1个回答

15

让我给你谈谈我的宏观视角。

宏基本上是一个代码 -> 代码函数。它以代码(一个Julia表达式)作为输入,并输出代码(另一个Julia表达式)。

这有什么用?它有多个目的:

  • 编译时复制和粘贴:您不必多次编写相同的代码,而是可以定义一个简短的宏,在您放置它的任何地方为您编写它。 (示例)

  • 领域特定语言(DSL):您可以创建特殊的语法,在宏代码 -> 代码转换后被纯Julia结构替换。这在许多软件包中用于定义特殊语法,例如此处此处

  • 代码生成:想象一下,您想编写一段非常长的代码,虽然很长,但非常简单,因为它具有某种重复自己相当琐碎的模式。手动编写该代码可能会很麻烦(甚至实际上是不可能的)。宏可以为您以编程方式生成代码。一个例子是for循环展开(参见此处此处)。但是,即使@time宏也不会做比在提供的Julia表达式周围放置一堆Base.time_ns()函数调用更多的事情。

  • 特殊字符串解析:如果您在Julia中键入文字3.2,它将被解析并解释为Float64。现在,想象一下,您想要提供一个数字文本,超出了Float64精度,但适合于BigFloat。键入big(3.123124812498124812498)将无法工作,因为首先将文本数字解释为Float64,然后将其传递给big函数。相反,您需要一种方法,在解析时告诉Julia这应该成为BigFloat。这由@big_str 3.2宏处理,为方便起见,也可以写为big"3.2"。后者只是语法糖。

可能还有许多宏的应用,但对我来说,这些是最重要的。

最后,让我引用Steven G. Johnson在JuliaCon 2019上的精彩演讲:

大多数情况下,不要使用元编程 :)


我理解得对吗,宏允许在运行时修改代码? - vasili111
@vasili111 编译时间,Julia 是一种 JIT 语言。 - schneiderfelipe

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