楼主: nuomin
398 1

Lisp Macros 5 [推广有奖]

  • 8关注
  • 61粉丝

版主

院士

34%

还不是VIP/贵宾

-

TA的文库  其他...

Lisp

计量模型入门与精通

威望
1
论坛币
170369 个
通用积分
8028.0780
学术水平
207 点
热心指数
257 点
信用等级
151 点
经验
944 点
帖子
2451
精华
0
在线时间
4062 小时
注册时间
2005-11-15
最后登录
2024-4-15

初级热心勋章 中级热心勋章 初级信用勋章

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
I _highly_ recommend On Lisp by Paul Graham and Let Over Lambda by Doug Hoyte. However: As you rightly point out, usually macros are just shorthand for lambdas (or more interestingly, closures). This is in some ways due to the inherent expressive power of the lambda calculus. As a first response, macros can help clarity; I routinely write ease-of-definition macros for special types of functions, etc. However, there are places where macros really save time: creating context and compile-time calculation.
Functions suffer from the fact that they require lexically-scoped arguments to be supplied explicitly, and as we know today dynamic/global variables have many drawbacks. Context creation combines the two: Variables are not global and you don't have to supply them as arguments everywhere in your code.
Compile-time calculation can be used for everything from optimization to automatic code generation.
Examples:
  • Anecdotes:

I am working on cl-ana (on github) and currently have it so that functions defined for numbers are available as element-wise versions for (nested) sequences; this is due to storing lambda-lists and function names at compile time and then automatically executing proper function definitions for sequences. The macro is transparent, just replace defun with defmath.
In some of my physics analysis code, I use functions which keep track of their dependencies and only run if necessary, i.e. if function-b calls function-a somewhere, then whenever function-a is set to re-run function-b automatically knows to re-run as well. This is useful when you have long chains of computation and update the data source at some point; you just specify the most basic function(s) which need re-running and call the master function, only the parts which need to be re-run are executed. This is a blend of compile-time calculation and optimization.
  • Anaphoric macros

How often do you find yourself testing the value of some expression, but then want that expression's value later on? Sure, you could go edit previous code to allow this, but that would take time and you potentially lose focus. Enter anaphoric macros.
Like aif:
  (defmacro aif (test then &optional else)    `(let ((it ,test))       (if it           ,then           ,else)))
It violates referential transparency, but we gain in essence a new special term "it" which is bound to whatever the containing aif set it to. The fact that language has pronouns is a big hint that often times it's better to express ideas within a context than to insist that everything be understandable via substitution.
Example:
  (aif (member x some-list)       it       (print "x is not in some-list"))
And you can do this for any conditional construct you can think of, e.g. awhen, acond, etc.
Another use for anaphoric macros: Ever wanted to write a recursive anonymous function but instead were forced to add a labels to your code? Try alambda:
  (defmacro alambda (lambda-list &body body)    `(labels ((self ,lambda-list                 ,@body))       #'self))
If you make heavy use of functions then you probably are prone to using recursion, so alambda may find quite a few good uses.
Let Over Lambda has even more examples (these are from On Lisp), but I won't bog down the page with them.
Gary Hollis
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Macros Macro acr CRO ROS

沙发
三江鸿 发表于 2022-10-30 09:46:46 来自手机 |只看作者 |坛友微信交流群
点个赞加点人气
感谢分享

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加JingGuanBbs
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-27 13:00