在Lisp或Scheme中是否存在整个程序转换宏?

Sha*_*rad 6 lisp macros scheme transformation

我已经看到一个答案:Lisp如何让你重新定义语言本身? Stack Overflow问题(由Noah Lavine回答):

宏并不是对语言的完全重新定义,至少据我所知(我实际上是一个Schemer;我可能是错的),因为有一个限制.宏只能占用代码的单个子树,并生成一个子树来替换它.因此,你不能编写整个程序转换宏,就像那样酷.

阅读本文之后,我很好奇是否在Lisp或Scheme(或其他语言)中存在"整个程序转换宏".

如果不是那么为什么?

  • 它没用,从不需要?
  • 通过其他方式可以实现同样的目的吗?
  • 即使在Lisp中也无法实现它?
  • 有可能,但没有尝试或实施过吗?

更新

一种用例,例如

在stumpwm代码中,这里的一些函数都在不同的lisp源文件中使用了一个动态/全局defvar变量*screen-list*,它在primitives.lisp中定义,但在screen.lisp,user.lisp,window.lisp中使用.(这里每个文件都有与一个方面或对象相关的函数,类,变量)

现在我想在闭包下定义这些函数,其中 *screen-list*变量可以通过let表单获得,它不应该是动态/全局变量,但是不要将这些函数移动到一个地方(因为我不希望这些函数丢失来自相关文件的位置)这样只有这些函数才能访问这个变量.

以上例如同样适用于标签和flet,因此我们可以进一步使它成为只需要变量,功能将可用于需要它的人.

注意一种方法可能是实现并使用一些宏defun_with_context进行defun,其中第一个参数是上下文,其中let,flet变量definend.但除此之外,Vatine和Gareth Rees回答说,它可以通过读者宏来实现.

Gar*_*ees 5

你引用Noah Lavine的话说:

宏只能占用代码的单个子树,并生成一个子树来替换它

这是普通宏的情况,但读取器宏可以访问输入流,并可以随意执行任何操作.

请参阅Hyperspec 部分2.2set-macro-character功能.


Sam*_*adt 5

在Racket中,您可以实现整个程序转换宏.请参阅有关定义新语言的文档部分.在Racket中有很多这样的例子,例如懒惰语言和Typed Racket.