(defun rmapcar (fn &rest args)
(if (some #'atom args)
(apply fn args)
(apply #'mapcar
#'(lambda (&rest args)
(apply #'rmapcar fn args))
args)))

这段代码第一眼看上去,怎么都像无限递归,不断的用&rest对参数做list,然后用mapcar做car,但是这段代码又是确确实实能运行的.仔细分析以后,可以肯定哪个函数的调用对参数多做了一次类似car的拆解.

当看到apply函数时,想起《Ansi Common Lisp》中对apply的描述

apply接受一个函数和任意数量的参数,但是最后一个参数必须是一个列表
Syntax:
apply function &rest args+ => result*

虽然很多函数都有&rest参数,由于&rest会自动把不定的参数组成一个列表,这个函数的说明就略显突兀了,于是查看了参数说明.

args---a spreadable argument list designator.
spreadable argument list designator n. a designator for a list of objects; that is, an object that denotes a list and that is a non-null list L1 of length n, whose last element is a list L2 of length m (denoting a list L3 of length m+n- whose elements are L1i for i < n- followed by L2j for j < m). ``The list (  (  )) is a spreadable argument list designator for the list (    ).''

发现第二个apply和平常的调用不同在于,这次有2个function,1个list.

平常调用apply:

(apply #'(lambda (&rest args) args) '(a b c))

平常调用函数:

 ((lambda (&rest args) args) 'd '(a b c))

&rest超过一个list的调用:

(apply #'(lambda (&rest args) args) 'd '(a b c))

在机器上运行上面3个调用,会发现第三个调用相当于对&rest中的参数做了一次拆解,最后一个列表又刚好是传入参数,曾被&rest包装过一次,在这里利用apply的这个特性,做了拆解,自然没有形成无限递归.

结论:一个函数使用由&rest传递进来的参数调用一个其他函数时,用apply调用那个函数,一次包装一次拆解刚好抵消.

《On Lisp》第四章第三节图4.6中的rmapcar函数中展现的apply陷阱的更多相关文章

  1. 《On Lisp》第四章第三节图4.3中的prune函数fix

    这个函数作者的原意是删除表中test位真的部分,并且表按原样返回. 作者给出的的测试用例如下: (prune #'evenp '(1 2 (3 (4 5) 6) 7 8 (9))) 返回结果是: (1 ...

  2. 微信小程序教学第四章第三节(含视频):小程序中级实战教程:详情-功能完善

    详情 - 功能完善 本文配套视频地址: https://v.qq.com/x/page/f0555nfdi14.html 开始前请把 ch4-3 分支中的 code/ 目录导入微信开发工具 这一节中, ...

  3. jQuery_第四章_思维图

    ---------------------------------------------------------------------------------------------------- ...

  4. 啊哈算法第四章第三节 层层递进-广度优先搜索 java实现

    package corejava; public class FourThree { static int [][]a=new int[50][50]; static int [][]b=new in ...

  5. 剑指offer-第四章解决面试题的思路(包含min函数的栈)

    题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,在该栈中,调用min,push及pop的时间复杂度都是O(1) 思路:定义两个栈分别为dataStack和minStack ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...

  7. C# Language Specification 5.0 (翻译)第四章 类型

    C# 语言的类型分为两大类:值类型(value type)和引用类型(reference type),而它们又都同时具有至少一个类型形参的泛型类型(generic type).类型形参(type pa ...

  8. 第四章 使用Docker镜像和仓库(二)

    第四章 使用Docker镜像和仓库(二) 回顾: 开始学习之前,我先pull下来ubuntu和fedora镜像 [#9#cloudsoar@cloudsoar-virtual-machine ~]$s ...

  9. JavaScript高级程序设计:第十四章

    第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继 ...

随机推荐

  1. PHP取整函数:ceil,floor,round,intval的区别详细解析

    floor -- 舍去法取整说明float floor ( float value ) 返回不大于 value 的下一个整数,将 value 的小数部分舍去取整.floor() 返回的类型仍然是 fl ...

  2. 使用C#进行图像处理的几种方法(转)

    本文讨论了C#图像处理中Bitmap类.BitmapData类和unsafe代码的使用以及字节对齐问题. Bitmap类 命名空间:System.Drawing 封装 GDI+ 位图,此位图由图形图像 ...

  3. oracle 创建用户

    /*分为四步 *//*第1步:创建临时表空间  */create temporary tablespace ycjy tempfile 'D:\oracledata\ycjy.dbf' size 50 ...

  4. ubuntu 14.04 compiz的ALT + TAB切换程序

    安装完ubuntu,发现不能使用ALT + TAB切换应用程序,翻遍所有百度结果,没有可行,都是拷这个拷那个...真实无语...FQgoogle,看的第一个就完美解决.记录下来,方便国人少走弯路. 首 ...

  5. SQL Server 数据库备份

    declare @filename varchar(1024) declare @SQLDB varchar(50) declare @path varchar(1024) set @path = N ...

  6. Excel with COM

    COM     excelApplication ; COM     workBooks ; COM     workSheets ; COM     workSheet ; COM     work ...

  7. Jmeter组件7. JDBC Connection Configuration & JDBC Request

    Jmeter同样可以测试数据库的性能,通过执行增删改查的语句,以下举的是oracle的例子 Step 1: 下载ojdbc14.jar包放到Jmeter lib包中,在test plan中配置,并且重 ...

  8. 使用struts通配符报错

    报错截图如下: 主要原因是:对大小写敏感. struts.xml StudentAction.java jsp页面:(重点就是这里,锚里面需要特别注意,大小写应该与struts.xml里面的保持一致, ...

  9. 如何在IDEA上 添加GIT和maven、mybatis插件

    IDEA工具上,添加GIT和maven.mybatis插件,相对比较简单: 首先下载GIT.maven.mybatis. 先添加GIT插件: 首先在IDEA找到file中找到setting,然后搜索g ...

  10. MongoDB(五)mongo语法和mysql语法对比学习

    我们总是在对比中看到自己的优点和缺点,对于mongodb来说也是一样,对比学习让我们尽快的掌握关于mongodb的基础知识. mongodb与MySQL命令对比 关系型数据库一般是由数据库(datab ...