博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
named let 递归和闭包的利器
阅读量:6576 次
发布时间:2019-06-24

本文共 1315 字,大约阅读时间需要 4 分钟。

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

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

这种写法的毛病在于:

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

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

 

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

(define (imake-list n member)  (let recur ((n n))    (if (= 1 n)        (cons member '())        (cons member (recur (- n 1))))))(imake-list 5 "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) '(1 2 3)) (imap + '(1 2 3) '(1 2 3) '(1 2 3))

 

转载于:https://www.cnblogs.com/xiangnan/p/3390253.html

你可能感兴趣的文章
【机器学习】--关联规则算法从初识到应用
查看>>
MOTO XT702添加开机音乐
查看>>
Python脚本日志系统
查看>>
B0BO TFS 安装指南(转载)
查看>>
gulp常用命令
查看>>
TCP(Socket基础编程)
查看>>
RowSet的使用
查看>>
每日一记--cookie
查看>>
WPF and Silverlight 学习笔记(十二):WPF Panel内容模型、Decorator内容模型及其他...
查看>>
FLUSH TABLES WITH READ LOCK 和 LOCK TABLES比较
查看>>
MySQL:创建、修改和删除表
查看>>
Java多线程程序设计详细解析
查看>>
IOS 7 Study - UISegmentedControl
查看>>
八、通用类型系统
查看>>
JQuery的ajaxFileUpload的使用
查看>>
Java分享笔记:使用keySet方法获取Map集合中的元素
查看>>
Java面向对象练习题之人员信息
查看>>
关于Integer类中parseInt()和valueOf()方法的区别以及int和String类性的转换.以及String类valueOf()方法...
查看>>
ios 控制器的生命周期
查看>>
C#动态代理
查看>>