functional-programming - 您可以用宏做什么不能用过程完成的事情?

标签 functional-programming scheme lisp

<分区>

我一直在阅读 sicp 试图理解方案,特别是宏。我注意到 sicp 根本不谈论宏。我在 Paul Graham 的网站上看到:

The source code of the Viaweb editor was probably about 20-25% macros. Macros are harder to write than ordinary Lisp functions, and it's considered to be bad style to use them when they're not necessary. So every macro in that code is there because it has to be.

所以我非常想知道如何编写宏以及它们的用途,所以我阅读了这个关于宏的网站:http://www.willdonnelly.net/blog/scheme-syntax-rules/ 但是该站点只是解释了如何编写“for”宏。我认为 Paul Graham 谈论 CL 而另一个博客谈论方案,但它们部分相同。 那么,wat 可以作为普通程序无法完成而必须使用宏来完成的示例吗?

编辑:我已经看到类似的 question ,但想问一下是否有某种疯狂的算法可以用宏来做,而这些算法不可能用过程来完成(除了那个问题的答案中描述的语法糖)。

最佳答案

宏是一个棘手的主题,我个人已经不止一次地改变了自己的观点,所以对所有事情都持保留态度。

如果您刚刚熟悉宏,您会发现最有帮助的是那些澄清或加速现有表达式的宏。

您可能接触过的一个这样的宏是 anaphoric 宏,它在今天仍然像 Paul Graham 创造这个词的那一天一样流行:

(define-syntax (aif x)
  (syntax-case x ()
    [(src-aif test then else)
     (syntax-case (datum->syntax-object (syntax src-aif) '_) ()
       [_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))

这些宏引入了“照应”变量,即 it,您可以在 if 语句的后续和替代子句中使用它,例如:

(aif (+ 2 7)
  (format nil "~A does not equal NIL." it)
  (format nil "~A does equal NIL." it))

这为您省去了键入 let 语句的麻烦——这在大型项目中可能会累加起来。

更广泛地说,改变程序结构的转换、动态生成“模板化”代码或以其他方式“破坏”规则(希望您足够了解以破坏!)是宏的传统领域。我可以不停地写我如何使用宏简化无数项目和作业——但我想你会明白的。

学习 Scheme 样式的宏有点令人生畏,但我向你保证,这里有 excellent guides to syntax-rules-style macros for the merely eccentric ,并且随着您获得越来越多的宏经验,您可能会得出这样的结论:它们是一个绝妙的主意,名副其实的“Scheme”。

如果你碰巧使用了Racket(以前称为PLT Scheme)--It has excellent documentation on macros ,甚至在此过程中提供了一些巧妙的技巧(我也猜想那里写的大部分内容都可以很容易地用另一种 Scheme 方言编写而不会出现问题)

关于functional-programming - 您可以用宏做什么不能用过程完成的事情?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38386080/

相关文章:

functional-programming - 具有相同字段的两条记录的模式匹配

ios - 如何使用后缀中的 CFBundleShortVersionString 动态获取 "Archive Name"(在编辑方案/存档/存档名称中)?

scheme - 是否有内置的 Racket 将元素作为列表重复 n 次?

lambda - 使用 let 重写表达式

java - Collectors.groupingBy() 中的映射值

swift - 将 Swift 序列转换为相邻对

perl - 我将如何用最少的代码在 Perl 中完成与 Prototype 的 Enumerator.detect 等效的操作?

python - 如何制作一个像lisp的 'mapcar'一样工作的python函数

c# - LISP 中的关联列表是否与 C# 中的字典相同?

coding-style - 减少,或显式递归?