深入了解lisp(clojure)-宏
来源:互联网 发布:贝伦赛丽40周年 知乎 编辑:程序博客网 时间:2024/05/16 07:30
本文由larrylgq编写,转载请注明出处:http://blog.csdn.net/larrylgq/article/details/7395261
作者:吕桂强
邮箱:larry.lv.word@gmail.com
lisp使用特殊操作符来扩展语法,但是在lisp中特殊操作符的数量是固定的,为了解决这个问题lisp引入了宏,宏并不直接做事,而是生成实际的业务代码。
宏的求值过程:接收S-表达式为参数,返回一个lisp展开式(ecpansion),对该展开式求值。
编译过程:在clojure中使用compile编译源文件的时候,将文件中所有宏递归展开成展开式,此时代码中只有函数调用形式和特殊形式。将展开后的代码编译成FASL文件,使用LOAD函数加载时会执行这些编译过的代码。
由于宏不会被直接求值的特性,所以我们定义的宏可以不是标准格式的lisp,每个宏都可以定义自己的语法。
相较于使用核心加上标准库的方式定义的语言,lisp可以通过宏来定义新的语法,并将它放在标准库里,而不是硬编码在语言核心。
当然你也可以将自己会大量复用的代码抽象成宏来使代码更简洁。
宏的结构:名字+形参列表+可选文档字符串+声明+lisp表达式体
一个简单的例子,使用宏实现
(defmacro while "Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil" {:added "1.0"} [test & body] `(loop [] (when ~test ~@body (recur))))
当我们这样调用的时候:
user=> (def a (atom 10)) #'user/auser=> (while (pos? @a) (do (println @a) (swap! a dec)))
将会在编译器产生如下代码:
(defn while [(pos? a) (do (println @a) (swap! a dec))]
(loop [] (
(when (pos? a)
(do (println @a) (swap! a dec))
(recur)
)
)))
符号使用:
反引号 :防止宏体内的表达式被evaluate。
波浪号:使用在在反引号里面,它的值会被替换。
~@:
替换某个具体元素。
- 深入了解lisp(clojure)-宏
- 深入了解lisp(clojure)-变量
- lisp家族之Clojure
- 现实世界的LISP:Clojure语言初探
- 为什么我喜欢Lisp语言(clojure)
- 深入了解宏
- Clojure 宏
- clojure解构(clojure destructuring)
- clojure解构(clojure destructuring)
- Macro in LISP (LISP中宏的要义)
- 用clojure实现《实用Common Lisp编程》中的单元测试框架
- 【转】现实世界的LISP:Clojure语言初探
- The Clojure (or Lisp) Equivalent of a Compound Boolean Test
- Lisp 匿名递归函数 v2:在 Common Lisp 中实现 Clojure 的 fn
- Clojure 学习入门(11)- 宏 macro
- 深入了解SOA(莫淘)
- 深入了解JSF(一)
- 深入了解JSF(二)
- boost_CURRENT_FUNCTION_
- 应用程序不被删除,获得admin权限,锁屏
- CR, LF, CR/LF 回车 换行
- 手势识别基本知识(一)
- linux中软链接与硬链接的区别
- 深入了解lisp(clojure)-宏
- 设计模式中类的关系
- JSP页面访问本地共享文件夹
- Linux用户管理安全宝典:密码防破解与帐号文件保护
- 常用Suse服务开通
- ubuntu 11.10 安装 sun-java6-jre 和 sun-java6-jdk
- Some troblshootings in DC/AD
- windows系统命令
- Linux初步学习 (四)