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))

named let 递归和闭包的利器的更多相关文章

  1. 浅谈javascript中的递归和闭包

    递归和闭包作为js中很重要的一环,几乎在前端的面试中都会涉及,特别闭包.今天前端组的组长冷不丁的问了我一下,粗略的回答了一下,感觉不太满足,于是重新学习了一下,写下本篇. 在说这个两个概念之前,我们先 ...

  2. 四、golang内置函数、递归、闭包、数组切片和map

    一.总体内容 1.内置函数.递归函数.闭包 2.数组和切片 3.map数据结构 4.package介绍 一.内置函数 注意:值类型用new来分配内存,引用类型用make来分配内存 1.close:主要 ...

  3. php闭包实现函数的自调用,也是递归

    php的闭包可能不常用,但是在某些场合之下还是可以考虑用php的闭包来实现某些功能的,比如递归,这里讲一下用php的闭包实现递归 //php闭包实现函数的自调用,也就是实现递归 function cl ...

  4. PHP闭包实现函数的自调用实现递归

    根据pathinfo访问对应得controller,如ip:port/home/index/index则会访问home目录下的IndexController的index方法:如果不指定pathinfo ...

  5. 递归转手工栈处理的一般式[C语言]

    是任意形式的递归,是化解的一般式. 主题所谓的“递归调用化解为栈处理”,意思是,将递归函数调用化解为“一个由stack_push stack_pop stack_top等函数调用组成的循环式子”.这里 ...

  6. 简学Python第三章__函数式编程、递归、内置函数

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

  7. 第四章 函数(JavaScript:语言精粹)

    函数包含一组语句,用来指定对象的行为,其代码可以用来重复使用.   一般来说,编程就是将一组需求分解成一组函数和数据结构的技能.   概览:函数对象 | 函数字面量 | 调用 | 方法调用模式 | 函 ...

  8. 简述 Ruby 与 DSL 在 iOS 开发中的运用

    阅读本文不需要预先掌握 Ruby 与 DSL 相关的知识 何为 DSL DSL(Domain Specific Language) 翻译成中文就是:"领域特定语言".首先,从定义就 ...

  9. JavaScript高级 函数表达式 《JavaScript高级程序设计(第三版)》

    函数表达式的特征 使用函数实现递归 使用闭包定义私有变量 前面我们说到定义函数有两种方式:函数声明.函数表达式. 两者的区别在于函数声明提升,前者在执行之前的上下文环境中直接被赋值,而后者不会. 一. ...

随机推荐

  1. 三,前端---JS最基本的创建对象的方法

    1:工厂模式 function createPerson(name, job){ var person = new Object(); person.name = name; person.job = ...

  2. [LeetCode] Longest Word in Dictionary 字典中的最长单词

    Given a list of strings words representing an English Dictionary, find the longest word in words tha ...

  3. Hibernate | Spring JPA | MySQL 使用过程遇到的一些问题

    1. 使用过程 2. 背景 3. 遇到问题 3.1 不指定Hibernate数据库方言,默认SQL生成方式 3.2 抛出异常Hibernate加入了@Transactional事务不会回滚 3.3 H ...

  4. [Codeforces 448C]Painting Fence

    Description Bizon the Champion isn't just attentive, he also is very hardworking. Bizon the Champion ...

  5. [AHOI2012]铁盘整理

    题目描述 输入输出格式 输入格式: 共两行.第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R.(1<=R<=100) 输出格式: ...

  6. Codeforces Round #460 E. Congruence Equation

    Description 题面 \(n*a^n≡b (\mod P),1<=n<=x\) Solution 令 \(n=(P-1)*i+j\) \([(P-1)*i+j]*a^{[(P-1) ...

  7. hdu4542 && ZOJ2562(反素数)

    反素数: 对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整 数,都有,那么称为反素数. 有两个特点: 1.一个反素数的质因子必是从2开始的质数 2.如果,那么必有 最常见的问题如 ...

  8. bzoj 4710: [Jsoi2011]分特产

    Description JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望 ...

  9. Mac Webview OC与JS交互实现

    1.首先,需要定义一个JS可识别的变量(如external)用于OC与JS交互 - (void)webView:(WebView *)sender didClearWindowObject:(WebS ...

  10. 利用css3+js实现简单带立体过渡效果的图片切换(chrome浏览器)

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...