named let和递归,闭包联系十分密切.而且还是提高性能的重要手段.先来看一个make-list函数的模拟,最原始的写法大概是:

(define (imake-list n member)
(if (= n)
(cons member '())
(cons member (imake-list (- n ) member))))

这种写法的毛病在于:

1.递归过程中,member变量可能需要在全局作用域中查找,比局部作用域查找要慢.

2.member是一个固定的参数,然而递归过程在不断重复将它传入imake-list.

这个时候你需要 named let,完美解决这2个问题:

(define (imake-list n member)
(let recur ((n n))
(if (= n)
(cons member '())
(cons member (recur (- n )))))) (imake-list "a")

具体过程:

1.let创建了一个内部函数recur.它接受一个参数,返回一个列表.

2.imake-list的n传递给了recur的n.而后者是在局部作用域.

3.递归过程转移到recur中进行,固定参数member成了它的自由变量.避免了重复传入的问题.

似乎迭代和递归会很频繁地用到这种技巧,例如很基本的函数map的模拟,也可以分为2个版本:

;原始低效版
(define (imap f x . y)
(if (null? y)
(if (null? x)
'()
(cons (f (car x)) (imap f (cdr x))))
(if (null? x)
'()
(cons (apply f (car x) (imap car y)) (apply imap f (cdr x) (imap cdr y)))))) ;named let高效版
(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))))))) (map + '(1 2 3) '( ) '(1 2 3))
(imap + '(1 2 3) '( ) '(1 2 3))

最新文章

  1. 我的基于asp.net mvc5 +mysql+dapper+easyui 的Web开发框架(1)数据库访问(0)
  2. 如何实时查看linux下的日志
  3. 亿级Web系统搭建——单机到分布式集群
  4. edittext 监听内容变化
  5. html之给文本框设置宽度和高度/input的无边框效果
  6. Hadoop系统架构
  7. Call to undefined function curl_init()解决方法
  8. Game of Life 解答
  9. HTML5实现涂鸦板
  10. js获取浏览器宽高
  11. Vue.js 入门
  12. Ant的使用
  13. Java不走弯路教程(4.Client-Server模式(1)-Server)
  14. Gradle初探
  15. Understanding HBase and BigTable
  16. apk的api级别不要低于26
  17. Async/Await是这样简化JavaScript代码的
  18. Python3 tkinter基础 Entry show textvariable 密码输入框
  19. 回归——继续我的ACM之路!!
  20. 匿名函数、闭包、lambda表达式、Block

热门文章

  1. Mybatis-简单基于源码了解获取动态代理对象
  2. [LeetCode] Open the Lock 开锁
  3. 规约模式(Specification Pattern)
  4. [USACO 04OPEN]MooFest
  5. ●Joyoi Normal
  6. 计蒜客NOIP2017提高组模拟赛(三)day2-数三角形
  7. 【无语凝噎(wordless)】
  8. solr6.6初探之配置篇
  9. redis启动失败
  10. ArrayList add方法的实现之扩容