不应滥用named let
> (define (f x) x)
> (define (g x) (let rec((x x)) x))
> (define a '(1 2 3)) > (f a)
( )
> (eq? a (f a))
#t
> (eq? a (g a))
#t > (define b (g a))
> (set-car! b )
> a
( )
>
可见,g函数的定义中,named let并未深拷贝x的值,它只是建立传入参数的引用而已.
那这也说明,如果一个函数所有参数在递归过程中都会发生改变,那么一般没必要用named let.
又如:
;切割named let版 ( ) -> ( )
(define (tail x n)
(let recur ((x x)(n n))
(if (null? x)
'()
(if (> n )
(recur (cdr x) (- n ))
(cons (car x) (recur (cdr x) (- n ))))))) ;切割原始版
(define (tail x n)
(if (null? x)
'()
(if (> n )
(tail (cdr x) (- n ))
(cons (car x) (tail (cdr x) (- n ))))))
原始版就是更好的.
但是,对于递归过程中函数所有参数都在变化的情形,有两种情况例外,仍然需要named let:
(1)函数要求返回递归过程中的某些变量的最终状态.例如求一个list的元素个数的函数定义:
(define (len x)
(let recur ((x x)(y ))
(if (null? x)
y
(recur (cdr x) (+ y )))))
由于需要一个变量来记录(cdr x)的次数,因此在内嵌函数recur中增加一个参数y来实现是非常合适的.
(2)处理不定参数的情形.这个可以用map来作非常好的说明:
(define (imap f x . y)
(if (null? y)
(let recur ((x x))
(if (null? x)
'()
(cons (f (car x)) (recur (cdr x)))))
(let recur ((x x) (y y))
(if (null? x)
'()
(cons (apply f (car x) (imap car y)) (recur (cdr x) (imap cdr y)))))))
显然,结合条件判断,named let能够将复杂情形转化为简单情形.思路是:
如果y是空表,那么imap等于一个只有1个参数recur函数.否则就等于2个参数的recur函数.而后者的参数传递过程中,我们又需要用到1个参数的情形:
(imap car y)
(imap cdr y)
这真是非常精妙的.
不应滥用named let的更多相关文章
- LINQ使用细节之.AsEnumerable()和.ToList()的区别
先看看下面的代码,用了 .AsEnumerable(): 1 var query = (from a in db.Table2 where a = SomeCondition3 select a.So ...
- linux面试题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取uu要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 ...
- Linux笔试常见填空题
一.填空题: 在Linux系统中,以 文件 方式访问设备 . Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. Linux文件系统中每个文件用 i节点 来标识. 全部磁盘块 ...
- Linux面试题汇总答案
转自:小女生的Linux技术~~~Linux面试题汇总答案~~ 一.填空题:1. 在Linux系统中,以 文件 方式访问设备 .2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的 ...
- linux 笔试题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来 ...
- Linux 面试题总结
一. 填空题1. 在Linux系统中,以 (文件) 方式访问设备 .2. Linux内核引导时,从文件 (/etc/fstab) 中读取要加载的文件系统.3. Linux文件系统中每个文件用 (索引节 ...
- linux常见问题集锦-1
http://www.cnblogs.com/itech/archive/2011/02/12/1952857.html 感谢作者分享 一.填空题:1. 在Linux系统中,以 文件 方式访问设备 . ...
- linux常见问题集锦
本文转自 http://bbs.chinaunix.net/thread-3668921-1-1.html,在此感谢作者分享 一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. ...
- linux面试题及答案
http://www.cnblogs.com/itech/archive/2011/02/12/1952857.html 一.填空题:1. 在Linux系统中,以 文件 方式访问设备 .2. Linu ...
随机推荐
- springmvc文件下载之文件名下划线问题终极解决方案
直接上代码:Action中代码片段. @RequestMapping("download")public String download(ModelMap model, @Mode ...
- mysql-5.7.18-winx64 免安装版配置
如题,最新的都是只有免安装版的,可以官网下载zip的压缩包. 下载后解压,如下 下面就开始配置 1.在path中添加环境变量 ;D:\coding\mysql-5.7.18-winx64\bin; ← ...
- 参考用bat文件
@echo off rem *************** start of 'main' set DEBUG= " (set TRACE=echo) else (set TRACE=rem ...
- 剥掉层层外衣后的RPC是什么样子的?
RPC,全称为Remote Procedure Call(远程过程调用).通俗一点讲就是在本地调用远程服务器上的功能.实现远程调用至少需要满足以下几个条件: 1.网络通信 2.序列化与反序列化 3.反 ...
- [Codeforces 864A]Fair Game
Description Petya and Vasya decided to play a game. They have n cards (n is an even number). A singl ...
- [CQOI2010]内部白点
Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟,所有内部白点同时变黑,直到不存在内部白点为止.你的任务是统计最后网格 ...
- 冰精冻西瓜[P3787洛谷]
题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃. 这些西瓜蔓具有神奇的性质,可以将经过它的 ...
- 【NOIP2017 OFO】
·奇怪的标题可能预示着这一篇博文不是讲算法或者分享题目的吧. [一只情绪化的兔子] 今年的11月12日出奇地比去年温暖.两场比赛结束后的我们在临走前去尝试了OFO共享单车,在成都电子科技大学 ...
- bzoj1531[POI2005]Bank notes 单调队列优化dp
1531: [POI2005]Bank notes Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 559 Solved: 310[Submit][Sta ...
- [bzoj4236]JOIOJI
来自FallDream的博客,未经允许,请勿转载,谢谢. JOIOJI桑是JOI君的叔叔.“JOIOJI”这个名字是由“J.O.I”三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJ ...