lisp钟macro到底是什么?

发布于 2022-08-25 12:01:30 字数 694 浏览 19 评论 9

再c中的定义是
  #define   MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
就是一个简单的替换
在编译器之外就可以实现

但在lisp中
(defmacro when (condition &rest body)
`(if ,condition (progn ,@body)))

在里面用到了语言语法成分,比如说,红色的部分,如果这样的话,macro的实现就是语言的一部分了,因为编译器要理解他,并执行它(when (> x 10) (print 'big))而不是简单的替换,产生代码(if (> x 10) (progn (print 'big)))
这是不是书上说的“Perhaps the biggest barrier to a proper understanding of macros is, ironically, that they're so well integrated into the language. ”

但是我还是理解不了,便一起是怎么执行这个宏,产生程序代码的

写得有一些乱,请大虾务必看看,谢谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

被翻牌 2022-09-01 18:51:08

CL-USER> (defmacro echo (binds &body body)                                                                                                                              
           `((lambda ,(mapcar #'(lambda (var) (if (consp var) (car var) var))                                                                                          
                              binds)                                                                                                                                    
               ,@body)                                                                                                                                                  
             ,@(mapcar #'(lambda (var) (if (consp var) (cadr var) nil))                                                                                                
                      binds)))
ECHO                                                                                                                                                                    
CL-USER> (echo ((x 2) (y 5)) (+ x y))
7     

;;; so power!!

家住魔仙堡 2022-09-01 18:50:53

原帖由 chenzengjie 于 2009-11-3 21:10 发表
你不要先入为主的认为宏就是简单的串处理, 替换连接什么的。
lisp程序不是串,  是符号表达式.

你可以认为在lisp里定义一个宏就是定义一个函数. 宏在展开时用参数调用函数, 返回的是一个表达式. 然后再执行返 ...

非常感谢,有的时候是好钻牛角尖

怪我鬧 2022-09-01 18:50:47

原帖由 xdshting 于 2009-11-3 20:22 发表

您可能没理解我的意思
比如
(defmacro haha (var)
      (list ’setq var nil))

这个宏定义,我们调用他(haha x),展开之后是(setq x nil).在这里,而不是简单的替换生成(list 'setq x nil),我的意思 ...

我好像理解你说的呀。

展开宏也是解释器负责的,先展开,然后执行。你看我引用的英文,就是你看的那一章里的:

it could expand all the macros in the form being interpreted and then interpret the resulting code,

or it could start right in on interpreting the form and expand macros when it hits them.

这两句各对应一种处理方式。

梦里南柯 2022-09-01 18:50:42

你不要先入为主的认为宏就是简单的串处理, 替换连接什么的。
lisp程序不是串,  是符号表达式.

你可以认为在lisp里定义一个宏就是定义一个函数. 宏在展开时用参数调用函数, 返回的是一个表达式. 然后再执行返回的这个表达式.

我不知道你现在学到哪里了. 不过你不应该在这里钻的太深, 向后看, 理解的全面了很自然就明白宏的原理.

再往后会接触到很多程序和数据混用, 互相作用的例子. 那才是重点.

初心 2022-09-01 18:50:28

原帖由 chenzengjie 于 2009-11-3 13:20 发表
生成程序的程序,  并不少见.
最常见的各种CGI(perl, python, php程序)生成html程序(当然html严格来说不能算程序设计语言), lex与yacc生成的C程序, 输出PostScript文件的各种程序实际上是在写PostScript这种语言的程序.
C的宏机制(预处理)很简单, 只作一些简单的串处理, 由一个程序(传统上叫cpp)或在编译器里实现; lisp的宏机制实际上由lisp本身来实现, 定义一个宏实际上低层就是在定义一个lisp程序.
这是lisp广为称道的一个特点: lisp并不区分程序和数据. 一个lisp程序(宏)输出一些数据, 这些数据其实是可以被执行的lisp程序.

就是这句最关键的没看懂
请你看看我上面的回帖,关键是他在编译/解释的时候执行了一遍,即执行了list函数

花开柳相依 2022-09-01 18:42:24

原帖由 win_hate 于 2009-11-3 00:07 发表
宏通常用来生成代码,你可以认为有个预处理的过程,即把宏展开。

您可能没理解我的意思
比如
(defmacro haha (var)
      (list ’setq var nil))

这个宏定义,我们调用他(haha x),展开之后是(setq x nil).在这里,而不是简单的替换生成(list 'setq x nil),我的意思是说,在展开的过程中list函数执行了,展开的过程不是简单的替换

编译器或者解释器,怎么会执行list的?

小…红帽 2022-08-31 20:33:12

Common Lisp 不合适入门. 它是作为实际需要而设计的'产业'级的lisp方言. 特性繁多, 宣宾夺主.

要学lisp, scheme更好. sicp这本书, 从头到尾基本没有讲宏.

很多讲C语言的书, 全都反对用宏. 主要是宏这种东西, 在记法上作手脚, 很难掌握, 出了问题不好找出来.
现代一点的语言基本上没有一个有宏机制的.

[ 本帖最后由 chenzengjie 于 2009-11-3 13:37 编辑 ]

迷离° 2022-08-31 11:43:37

生成程序的程序,  并不少见.
最常见的各种CGI(perl, python, php程序)生成html程序(当然html严格来说不能算程序设计语言), lex与yacc生成的C程序, 输出PostScript文件的各种程序实际上是在写PostScript这种语言的程序.
C的宏机制(预处理)很简单, 只作一些简单的串处理, 由一个程序(传统上叫cpp)或在编译器里实现; lisp的宏机制实际上由lisp本身来实现, 定义一个宏实际上低层就是在定义一个lisp程序.
这是lisp广为称道的一个特点: lisp并不区分程序和数据. 一个lisp程序(宏)输出一些数据, 这些数据其实是可以被执行的lisp程序.

北方。的韩爷 2022-08-31 10:44:44

宏通常用来生成代码,你可以认为有个预处理的过程,即把宏展开。

When Lisp is interpreted, rather than compiled, the distinction between macro expansion time and runtime is less clear because they're temporally intertwined . Also, the language standard doesn't specify exactly how an interpreter must handle macros--it could expand all the macros in the form being interpreted and then interpret the resulting code, or it could start right in on interpreting the form and expand macros when it hits them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文