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. 一日一练-CSS CSS中percentage百分值的使用

    子曰:学好百分值,考试考百分 首先是确定CSS 中的percentage 都可以应用在CSS 中的哪些属性,以及这些属性的值如何进行计算的,参考CSS 参考手册进行统计. 定位(Positioning ...

  2. 从零开始系列之vue全家桶(1)安装前期准备nodejs+cnpm+webpack+vue-cli+vue-router

    写在前面: 什么是全家桶? 包含了vue-router(http://router.vuejs.org),vuex(http://vuex.vuejs.org), vue-resource(https ...

  3. [LeetCode] Valid Parenthesis String 验证括号字符串

    Given a string containing only three types of characters: '(', ')' and '*', write a function to chec ...

  4. .NET CORE 2.0之 依赖注入在类中获取IHostingEnvironment,HttpContext

    在.NET CORE 中,依赖注入非常常见, 在原先的 HttpContext中常用的server.Mappath已经么有了如下: HttpContext.Current.Server.MapPath ...

  5. [WC 2010]重建计划

    Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案, ...

  6. [ZJOI2017]树状数组

    Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道 基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来 ...

  7. [USACO09FEB]改造路Revamping Trails

    题目描述 Farmer John dutifully checks on the cows every day. He traverses some of the M (1 <= M <= ...

  8. POJ1222熄灯问题

    千年老题,以前用枚举做,现在用高斯消元做 自由元直接做成0即可 #include<cstdio> #include<cstdlib> #include<algorithm ...

  9. NOIP2014-5-17模拟赛

    Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 "来来来,学 ...

  10. hdu 2871 线段树(各种操作)

    Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...