gpt4 book ai didi

macros - 宏应该有副作用吗?

转载 作者:行者123 更新时间:2023-12-04 00:56:42 25 4
gpt4 key购买 nike

宏扩展可以(或应该)有副作用吗?例如,这是一个宏,它实际上在编译时抓取网页的内容:

#lang racket

(require (for-syntax net/url))
(require (for-syntax racket/port))

(define-syntax foo
(lambda (syntx)
(datum->syntax #'lex
(port->string
(get-pure-port
(string->url
(car (cdr (syntax->datum syntx)))))))))

然后,我可以做 (foo "http://www.pointlesssites.com/")它将被替换为 "\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\r\n\t <and so on>"
这是好习惯吗?我是否保证 Racket 只会运行此代码一次?如果我添加一个 (display "running...")行到宏,它只打印一次,但我不想从一个例子中概括......

PS - 我问的原因是因为我实际上认为这有时真的很有用。例如 this是一个库,它允许您(在编译时)从 Google API 发现服务加载发现文档并自动为其创建包装器。我认为如果库实际上是从网络而不是从本地文件中获取发现文档,那将是非常酷的。

另外,举一个具有不同类型副作用的宏的示例:我曾经构建了一个宏,它将 Racket 的一小部分转换为(eta 扩展的)lambda 演算(当然,它仍然可以在 Racket 中运行)。每当宏完成函数的翻译时,它会将结果存储在字典中,以便以后调用宏可以在自己的翻译中使用该函数定义。

最佳答案

简短的回答
宏有副作用很好,但您应该确保您的程序在提前编译时不会改变行为。
更长的答案
带有副作用的宏是一个强大的工具,它可以让你做一些让程序更容易编写的事情,或者实现一些根本不可能的事情。但是在宏中使用副作用时需要注意一些陷阱。幸运的是,Racket 提供了所有工具来确保您可以正确执行此操作。
最简单的宏副作用是您使用一些外部状态来查找要生成的代码。您在问题中列出的示例(阅读 Google API 描述)就是这种类型。一个更简单的例子是 include宏:

#lang racket
(include "my-file.rktl")
这将读取 myfile.rktl 的内容并将其放在 include 的正确位置使用表格。
现在, include不是构建程序的好方法,但这在宏中是一种非常良性的副作用。如果你提前编译文件,它的工作原理是一样的,因为 include 的结果是文件的一部分。
另一个不好的简单示例是这样的:
#lang racket
(define-syntax (show-file stx)
(printf "using file ~a\n" (syntax-source stx))
#'(void))

(show-file)
那是因为 printf仅在编译时执行,因此如果您编译使用 show-file 的程序提前(与 raco make 一样)然后 printf然后会发生,并且在程序运行时不会发生,这可能不是本意。
幸运的是,Racket 有一种技术可以让你编写像 show-file 这样的宏。有效地。基本思想是留下实际执行副作用的残留代码。特别是,您可以使用 Racket 的 begin-for-syntax为此目的而形成。这是我要写的 show-file :
#lang racket
(define-syntax (show-file stx)
#`(begin-for-syntax
(printf "using file ~a\n" #,(syntax-source stx))))

(show-file)
现在,而不是在 show-file 时发生宏被扩展, printf发生在 show-file 的代码中生成,源嵌入在扩展语法中。这样,您的程序在提前编译的情况下仍能正常工作。
宏的其他用途也有副作用。 Racket 中最突出的功能之一是用于模块间通信——因为 require不会产生需要模块可以获得的值,在模块之间进行通信最有效的方法是使用副作用。要在存在编译的情况下进行这项工作,需要与 begin-for-syntax 几乎完全相同的技巧。 .
这是 Racket 社区,尤其是我思考过很多的话题,并且有几篇学术论文讨论了它是如何工作的:
Composable and Compilable Macros: You want it when? ,马修·弗拉特,ICFP 2002
Advanced Macrology and the Implementation of Typed Scheme , Ryan Culpepper、Sam Tobin-Hochstadt 和 Matthew Flatt,2007 年方案研讨会
Languages as Libraries , Sam Tobin-Hochstadt、Ryan Culpepper、Vincent St-Amour、Matthew Flatt 和 Matthias Felleisen,PLDI 2011

关于macros - 宏应该有副作用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13081328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com