不应滥用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 ...
随机推荐
- LAMP+Wordpress搭建博客
作为一名技术控,看到别人都有专属于自己的博客,小夜也忍不住自己操刀做个自己的博客.有兴趣的童鞋接下来可要认真地练习比对哦.如果出现错误也不要着急上火,咱们可以交流学习.我们的口号是:遇水搭桥,遇山凿山 ...
- Jenkins配置Gogs webhook插件
前言 我们在前面使用Jenkins集合Gogs来进行持续集成的时候,选择的是Jenkins定时检测git仓库是否有更新来决定是否构建.也就是说,我们提交了代码Jenkins并不会马上知道,那么我们可以 ...
- js 的作用域 域解析 分析
作用域链 函数每次执行时,浏览器都会在函数中开启一个地方用来存储函数内的局部数据.(声明在函数内的局部变量),这个地方就叫做作用域([scopes]) 作用域链 变量与函数的查找规则:当我们在 ...
- [HNOI2012]永无乡
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- Fliptile 翻格子游戏
问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec 内存限制: 128 MB 题目描述 Farmer John knows that an intell ...
- LOJ #6119. 「2017 山东二轮集训 Day7」国王
Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...
- 左偏树(BZOJ4003)
左偏树打个标记,没了. #include <cstdio> #include <vector> using namespace std; typedef long long l ...
- linux 下文件误删恢复
linux 下文件误删恢复 0x01 事件背景 某天晚上写代码的时候,本来想删除当前目录下一个叫xxx的文件夹 rm -rdf ./xxx/*, 结果光顾着和人说话,一不留神手贱把命令敲成了rm -r ...
- Mysql 基于GTID的主从复制(实操)
实现环境: Master 主:192.168.0.102 (Mysql 5.6.36) Slave 从 :192.168.0.103 (Mysql 5.6.36) 步骤1.在主DB服务器上建立复制账 ...
- sharepoint环境安装
SharePoint 2013 测试环境安装配置指南 软件版本 Windows Server 2012 标准版 SQL Server 2012 标准版 SharePoint Server 2013 企 ...