Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >与-主义-绑定

与-主义-绑定
EN

Code Review用户
提问于 2012-04-12 19:19:32
回答 2查看 244关注 0票数 2

4(根据Rainer Joswig的反馈进行修改):

代码语言:javascript
运行
AI代码解释
复制
(defmacro with-gensyms ((&rest names) &body body)
  `(let ,(loop for n in names collect `(,n (gensym)))
     ,@body))

(defmacro let-alist ((&rest lookups) alist &body body)
  (with-gensyms (alist-form)
    `(let ((,alist-form ,alist)) 
       (let ,(loop for l in lookups 
           if (keywordp l)
             collect `(,(intern (symbol-name l)) (cdr (assoc ,l ,alist-form)))
           else
             collect `(,l (cdr (assoc ',l ,alist-form))))
     ,@body))))

这个修订版仍然可以用同样的方式使用。

代码语言:javascript
运行
AI代码解释
复制
> (defparameter test '((|foo| . 1) (:bar . 2) (baz . 3)))
TEST
> (let-alist (:bar |foo| baz) test
       (list |foo| bar baz))
(1 2 3)

但是宏只展开传入的alist表单一次。以下是slime-macroexpand-1的输出:

代码语言:javascript
运行
AI代码解释
复制
(LET ((#:G1299 TEST))
  (LET ((BAR (CDR (ASSOC :BAR #:G1299)))
        (|foo| (CDR (ASSOC '|foo| #:G1299)))
        (BAZ (CDR (ASSOC 'BAZ #:G1299))))
    (LIST |foo| BAR BAZ)))

欢迎所有评论,但具体而言(按重要性下降的顺序排列),

  • 你能想到一个好的文档吗?
  • 你能想到这会爆炸的情况吗?
  • 是否有一个内置宏做同样的事情,或接近它?
EN

回答 2

Code Review用户

回答已采纳

发布于 2012-04-14 05:53:07

它的主要问题是alist- -宏的变量。

代码语言:javascript
运行
AI代码解释
复制
CL-USER > (pprint (macroexpand-1 '(let-alist (:bar |foo| baz)
                                      (this-function-takes-a-long-time-or-has-side-effects)
                                    (list |foo| bar baz))))

(LET ((BAR (CDR (ASSOC :BAR (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS))))
      (|foo|
       (CDR (ASSOC '|foo| (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS))))
      (BAZ
       (CDR (ASSOC 'BAZ (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS)))))
  (LIST |foo| BAR BAZ))

如您所见,函数被多次展开到代码中。

规则1:始终检查扩展是否有问题。

规则2:不要将相同的代码多次展开到代码中。

阅读Paul的“On”(免费下载),了解公共Lisp中宏的各种缺陷,以及如何处理这些缺陷。

对于上面的内容,您需要生成一个新的唯一变量并绑定一次值。

票数 2
EN

Code Review用户

发布于 2012-04-14 10:02:54

这里有一个实现,它允许对作者中的值进行读和写访问。

首先,定义一个使用符号-宏的宏,其中主体中的绑定符号展开为在运算符中访问该符号的值的代码:

代码语言:javascript
运行
AI代码解释
复制
(defmacro with-alist% (alist-entries instance-form &body body)
  `(symbol-macrolet 
     ,(loop for (alist-binding alist-entry) in alist-entries
            collect `(,alist-binding (cdr (assoc ',alist-entry ,instance-form))))
     ,@body))

并测试它:

代码语言:javascript
运行
AI代码解释
复制
(defparameter *al* (list (cons 'foo 5) (cons 'bar 'a) (cons 'baz "z")))
*AL*
CL-USER> 
(print *al*)

((FOO . 5) (BAR . A) (BAZ . "z")) 
((FOO . 5) (BAR . A) (BAZ . "z"))
CL-USER> 
(with-alist% ((foo foo) (bar bar)) *al*
  (format t "foo=~a, bar=~a~%" foo bar)
  (setf foo 1)
  (setf bar "a") ...)
foo=5, bar=A
foo=1, bar=a 
NIL
CL-USER> 
(print *al*)

((FOO . 1) (BAR . "a") (BAZ . "z")) 
((FOO . 1) (BAR . "a") (BAZ . "z"))
CL-USER> 

请注意,不仅可以使用绑定符号进行打印,还可以使用setf符号,这将映射到更改与该符号相关的值。这是使用符号-宏(而不是let)提供的。另外,如果您阅读了具有-槽的源代码,至少对于CCL,符号-宏是如何实现该宏的。再一次,我正致力于一种类似的-插槽句法感觉。

如果您有一个混合关键字和符号的列表,with- but %的效果就足够好了,但是我认为大多数情况下只有符号,这意味着在使用该函数时会有大量的代码重复,例如:

代码语言:javascript
运行
AI代码解释
复制
(with-alist% ((foo foo) (bar bar)) *al*

请注意如何列出每个列表条目两次。如果你希望绑定符号和列表条目总是一样的话,该怎么办?如果你能这样做就太好了:

代码语言:javascript
运行
AI代码解释
复制
(with-alist (foo bar) *al*

而这个宏:

代码语言:javascript
运行
AI代码解释
复制
(defmacro with-alist (alist-entries instance-form &body body)
  `(with-alist% ,(mapcar (lambda (alist-entry)
                           (if (consp alist-entry)
                             `,alist-entry
                             `,(list alist-entry alist-entry)))
                         alist-entries)
                ,instance-form
                ,@body))

用法:

代码语言:javascript
运行
AI代码解释
复制
(print *al*)
CL-USER> 
((FOO . 1) (BAR . "a") (BAZ . "z")) 
((FOO . 1) (BAR . "a") (BAZ . "z"))
CL-USER> 
(with-alist (foo (bar% bar)) *al*
  (format t "foo=~a, bar=~a~%" foo bar%)
  (setf foo 5)
  (setf bar% 'a) ...)
foo=1, bar=a
foo=5, bar=A
NIL
CL-USER> 
(print *al*) 

((FOO . 5) (BAR . A) (BAZ . "z")) 
((FOO . 5) (BAR . A) (BAZ . "z"))
CL-USER> 
REPL    

我同意Rainer关于只评估实例-表单一次的评论,当您只想要读取访问权限时。但是,如果您想要进行读/写访问,那么每次在正文中找到绑定符号时,都需要展开实例窗体。否则,您将写入实例-表单的let绑定;而不是实例-表单;因此,实例-表单不会更改。

对于通用Lisp宏编程来说,一个很好的阅读绝对是在Lisp上,而且还可以在Lambda上进行。通过LOL是一项重要的时间投资,但如果你想提高你常用的lisp宏编程技能的话,这是很值得的。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/10843

复制
相关文章
Hadoop 任务运行失败
任务运行失败最常见的情况是 map 任务或 reduce 任务中的用户代码抛出运行异常。如果发生这种情况,任务 JVM 会在退出之前向其父 application master 发送错误报错。错误报告最后被记入用户日志中。application master 会将此次任务尝试标记为 failed (失败),并释放容器以便资源可以为其他任务使用。
smartsi
2019/08/07
3K0
spark任务之Task失败监控
在spark程序中,task有失败重试机制(根据 spark.task.maxFailures 配置,默认是4次),当task执行失败时,并不会直接导致整个应用程序down掉,只有在重试了 spark.task.maxFailures 次后任然失败的情况下才会使程序down掉。另外,spark on yarn模式还会受yarn的重试机制去重启这个spark程序,根据 yarn.resourcemanager.am.max-attempts 配置(默认是2次)。
UFO
2018/08/29
2.9K0
Celery 4.3.0 任务失败重试机制
在异步调用任务中经常需要调用第三方的api请求,如果一次执行失败,则应该进行重试执行。否则,如果在执行一些连续性的chain链条任务,前面执行失败,那么后续的也就不用执行了。
Devops海洋的渔夫
2019/10/23
3.8K0
GPU内存分级
在NVIDIA的GPU中,内存(GPU的内存)被分为了全局内存(Global memory)、本地内存(Local memory)、共享内存(Shared memory)、寄存器内存(Register memory)、常量内存(Constant memory)、纹理内存(Texture memory)六大类。这六类内存都是分布在在RAM存储芯片或者GPU芯片上,他们物理上所在的位置,决定了他们的速度、大小以及访问规则。
刘盼
2018/07/26
7.2K0
GPU内存分级
独家 | ChatGPT可以解决分级和分类这样的简单机器学习任务
作者:Damir Yalalov  翻译:陈超校对:赵茹萱 本文约1100字,建议阅读5分钟本文介绍了ChatGPT如何解决简单的机器学习任务并给出了鸢尾花分类和城市预测两个案例。 一句话概括: ChatGPT可以帮助你完成简单的机器学习任务——以下是方法: ChatGPT是一个聊天机器人,可以帮助你完成简单的机器学习任务,例如分级和分类任务。 它会用一种自然语言处理算法来理解你的问题并提供准确的答案。 你可以给ChatGPT提供更多的数据用以训练它实现更加准确地输出。这一工具设计的初衷就是为了方便使用,并
数据派THU
2023/04/25
4400
独家 | ChatGPT可以解决分级和分类这样的简单机器学习任务
MCE | 间歇性禁食增强抗癌疗效
越来越多的研究表明,“禁食”不仅与免疫系统调控 、血糖调节有关,还对多种疾病的治疗有改善效果,如心血管疾病和癌症等。
MedChemExpress
2023/03/16
3430
MCE | 间歇性禁食增强抗癌疗效
车站分级 拓扑排序
车站分级 从起点到终点,只会在大于等于它等级的站点停靠,则小于它的不停靠 就从小于它的连一条边到它,然后拓扑 #include <bits/stdc++.h> #define pir pair<int,int> using namespace std; const int N = 1050; int in[N],n,m,ans; int book[N][N],s[N][N]; int vis[N]; queue<pir> q; vector<int> g[N]; int read(){ int x=0,
用户2965768
2019/04/17
4580
【Google Play】IARC 年龄分级 ( IARC 国际年龄分级联盟 | Google Play 设置应用年龄分级 )
【Google Play】创建 Google 开发者账号 ( 注册邮箱账号 | 创建开发者账号 ) 【Google Play】创建并设置应用 ( 访问权限 | 内容分级 | 受众群体 | 类别及联系方式 | 商品详情 )
韩曙亮
2023/03/29
2.5K0
【Google Play】IARC 年龄分级 ( IARC 国际年龄分级联盟 | Google Play 设置应用年龄分级 )
VS2010 网站发布失败: TransformXml任务意外失败 问题解决
今天发布网站时意外出现了发布失败的提示:“TransformXml”任务意外失败。
KenTalk
2018/09/11
1.4K0
Storm客户端提交任务失败原因分析
storm客户端提交topology失败: java.lang.RuntimeException: org.apache.thrift7.transport.TTransportException at backtype.storm.StormSubmitter.submitTopology(StormSubmitter.java:141) at backtype.storm.StormSubmitter.submitTopologyWithProgressBar(Storm
囚兔
2018/05/30
2K0
Gradle如何在任务失败后继续构建
如果我们运行Gradle构建并且其中一项任务失败,则整个构建将立即停止。因此,我们可以快速反馈构建状态。如果我们不想这样做,并且希望Gradle执行所有任务,即使某些任务可能失败了,我们也可以使用命令行选项--continue。当我们使用--continue命令行选项时,Gradle将执行从属任务没有失败的所有任务。这在多模块项目中也很有用,即使在某些项目中测试可能失败,我们也可能希望构建所有项目,因此我们可以全面了解所有模块的失败测试。
FunTester
2019/12/04
1.6K0
勒索软件新技术趋势:间歇性加密
2021 年夏天,LockFile 勒索软件是首批引入间歇性加密技术的勒索软件家族之一。后来,越来越多的勒索软件都应用了这一技术。
FB客服
2022/11/14
9660
勒索软件新技术趋势:间歇性加密
P1983 车站分级
题目描述 一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站。每个火车站都有一个级别,最低为 1 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车
attack
2018/04/13
5880
P1983 车站分级
解决ASP.NET MVC间歇性响应缓慢
经查看发现好多地方设置了 $.ajaxSettings.async = false;,方法执行完毕后没有设置异步。 全部修改之后,发现请求还是慢,打断点发现控制台显示耗时几十秒的请求,实际执行一两秒左右,前端同时发送5个Ajax请求,结果却是同步返回的,或者可以说后端做了同步的处理。
鱼找水需要时间
2023/02/16
7250
数据的分类和分级
《中华人民共和国网络安全法》第二十一条规定国家实行网络安全等级保护制度。网络运营者应当按照网络安全等级保护制度的要求,履行下列安全保护义务,保障网络免受干扰、破坏或者未经授权的访问,防止网络数据泄露或者被窃取、篡改:同时提到采取数据分类、重要数据备份和加密等措施。
Dlimeng
2023/06/30
1.7K0
主机名修改后导致计划任务失败
原来在一台Windows 2008服务器上配置了一个SVN UPDATE的计划任务,定期将版本库中的最新版本抓取到本地。在主机名更改后,计划任务执行失败,提示“所指定的账户名称无效”。
大江小浪
2018/07/24
1.2K0
主机名修改后导致计划任务失败
scrapy间歇性响应为空/降速/缓存
使用 scrapy访问豆瓣的搜索接口时,莫名会出现response json数据为空的情况。 加上回调重新请求 (要设置dont_filter=True 防止被过滤), 还是会出现异常。 最后发现是请求速度过快导致的。
李玺
2021/11/22
7790
scrapy间歇性响应为空/降速/缓存
使用elastic job 不分片任务加载失败的可能原因
有一个任务是每10分钟,加载一次过去20分钟的内容,但是总有加载漏掉的时候。 此情况出现3次了,事不过三。看了服务也一直跑得很健康。
MickyInvQ
2020/09/27
8000
使用elastic job 不分片任务加载失败的可能原因
SDN:优雅的间歇性访问限制
一、项目简介 目的:设有一台PC机(Host1),一台Web服务器(Host2)提供简单的静态网页访问服务。通过RYU控制网络流,限制PC访问服务器的频率,如两次访问的间隔不能低于5秒。 应用场景: ①为 付费用户 和 免费用户 提供差异化服务 ②小型站点、个人站点、未做优化站点的负载缓解 ③…… 在详细了解TCP三次握手、四次挥手、RST强制重置,以及HTTP包交互全程的基础上,本项目达成了以下特色: 限制访问时,返回给PC友好的WEB页面提示,而不是仅仅通过流表把包丢弃,以及由此导致的PC用户浏览器持续
SDNLAB
2018/04/03
9670
SDN:优雅的间歇性访问限制
点击加载更多

相似问题

用于批量传输的WinUSB事件

10

为什么WinUsb_WritePipe用异步winusb返回错误997?

125

.NET中的异步传输控制协议通信

40

WinUSB安装

10

取消控制台按键中的异步方法

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文