racket学习-call/cc (let/cc)
Drracket continuation
文中使用let/cc代替call/cc
Racket文档中,let/cc说明为:
(let/cc k body ...+)
Equivalent to (call/cc (lambda (k) body ...)).
首先,通过一个简单的函数来测试下continuation,注意,下面的函数执行会导致无限循环
#lang racket
(define r #f)
(define (f) (let/cc k ;开始捕获continuation,从let/cc开始直到闭括号位置
(set! r k) ;将continuation保存到变量r中
(println 1) ;continuation内部代码,与普通代码一样执行,没有区别
(r) ;调用continuation,将导致跳过之后的代码,执行continuation之后的代码即(println 3)
(println 2) ;上一句调用了continuation,因此此句被跳过,不会执行
) ;continuation捕获到此结束
(println 3) ;这是continuation之后的第一句代码,无论在何处调用continuation(r或k)时,都将从此句开始执行
(println 4)
(r) ;再次调用continuation,将导致再次从continuation结束的地方开始执行,输出3,4后又调用此句,因此导致无限循环
(println 5) ;上一句调用continuation,从continuation之后开始执行,因此这句不会执行
) ;函数结束,continuation范围也结束
(println "end") ;此句位置虽在continuation后,但是在函数f之外,因此这句也不会执行
以上代码执行时,会首先输出1,然后无限循环输出3和4,不会输出end,由此例可以看出:
continuation定义从let/cc开始,到闭括号结束,其中BODY部分与其他代码一样执行,没有特殊,调用continuation时,从continuation结束后第一行开始执行,不会
执行continuation内部的代码
continuation后续逻辑,只包含continuation所在函数,与函数外的代码无关
下面的函数,由《Teach Yourself Scheme in Fixnum Days》中13.3中的tree->generator简化而来.
#lang racket
(define p
(letrec
((caller #f)
(generate‐leaves
(lambda ()
(let/cc continuation-1
(set! generate‐leaves
(lambda ()
(continuation-1 'resume)))
(caller 21))
(let/cc continuation-2
(set! generate‐leaves
(lambda ()
(continuation-2 'resume)))
(caller 22))
(caller '()))))
(lambda ()
(let/cc k
(set! caller k)
(generate‐leaves)))))
(p)
(p)
过程分析:
1、定义函数p,函数p为letrec的返回,即匿名函数
(lambda ()
(let/cc k
(set! caller k)
(generate‐leaves)))
此时,函数尚未执行,因为caller为空,generate‐leaves为6-17行的函数
2、调用函数p,首先捕获continuation并赋值给caller,相当于注册了一个回调函数,下次调用caller时,函数从continuation之后执行
注意,函数generate‐leaves在捕获continuation的内部,因此调用caller时,不会再次调用generate‐leaves,continuation之后没有代码,因此函数p的返回值即为调用caller的参数
3、调用函数generate‐leaves,捕获当前位置的continuation,并修改函数generate‐leaves为调用当前continuation-1,然后调用caller,程序跳转到caller之后开始执行,caller之后没有代码,因此函数p返回,返回值为caller调用的参数21
4、再次调用函数p,同步骤2
5、再次调用函数generate‐leaves,此时generate‐leaves已经在步骤3中被重新绑定为调用continuation-1,因此调用generate‐leaves,将从continuation-1之后开始执行,即从12行开始执行,捕获continuation-2,重新绑定函数generate‐leaves,并返回值22
racket学习-call/cc (let/cc)的更多相关文章
- Adobe CC Family (CC 2015) 大师版
Adobe CC Family (CC 2015) 大师版 v5.6#2 ###请彻底卸载旧版后再安装本版! 更新 Adobe Digital Publishing CC 2016.1更新 Adobe ...
- Adobe 系列软件通用破解方式(animate cc,Photoshop cc,Flash cc)等
破解之前准备工作: ①:安装好 试用版的 Adobe软件 ②:下载好破解软件: amtemu.v0.9.2-painter,下载地址:链接:http://pan.baidu.com/s/1nvNR74 ...
- cc.progressFromTo cc.progressTo(action 在duration中ProgressTimer的Percentage变化)
let progressTimer= new cc.ProgressTimer(new cc.Sprite(fileName));this.addChild(progressTimer);progre ...
- racket 学习笔记
length: (define (my-length lst) (if (empty? lst) 0 (+ (my-length (rest lst)) 1))) map: (define (my-m ...
- muduo网络库源码学习————Timestamp.cc
今天开始学习陈硕先生的muduo网络库,moduo网络库得到很多好评,陈硕先生自己也说核心代码不超过5000行,所以我觉得有必要拿过来好好学习下,学习的时候在源码上面添加一些自己的注释,方便日后理解, ...
- 学习:CC断点
断点介绍: shark恒老师说有四种说法,但是其实都是相同的 第一个读法:普通断点 第二个读法:F2断点 第三个读法:INT3断点( int3其实就是汇编指令 ) 第四个读法:CC断点 (CC其实就是 ...
- Linux CC攻击脚本
CC(ChallengeCollapsar)主要是用来攻击页面的.大家都有这样的经历,就是在访问论坛时,如果这个论坛比较大,访问的人比较多,打开页面的速度会比较慢,访问的人越多,论坛的页面越多,数据库 ...
- PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等
页面导航: 首页 → 网络编程 → PHP编程 → php技巧 → 正文内容 PHP安全 PHP开发中常见的安全问题详解和解决方法(如Sql注入.CSRF.Xss.CC等) 作者: 字体:[增加 减小 ...
- call/cc 总结 | Scheme
call/cc 总结 | Scheme 来源 https://www.sczyh30.com/posts/Functional-Programming/call-with-current-contin ...
随机推荐
- linux 下安装及查看java的安装路径
一.Linux下安装JDK 1.下载文件 从官网下载合适版本如:jdk-8u191-linux-x64.tar.gz 2.安装文件 1.在 /usr/ 目录下创建 java文件夹mkdir /usr/ ...
- pycharm中无法调用pip的安装包
https://blog.csdn.net/sinat_23619409/article/details/79962518 较详细:https://blog.csdn.net/weixin_41287 ...
- 详解js面向对象编程
转自:http://segmentfault.com/a/1190000000713346 基本概念 ECMA关于对象的定义是:”无序属性的集合,其属性可以包含基本值.对象或者函数.“对象的每个属性或 ...
- Python: Socket网络编程,多线程处理小Demo
一个简单的例子,深入研究一下socket的多线程处理任务 Server端: #!/usr/bin/env python #encoding:utf8 # # 注意:定义encoding时必须在第二行 ...
- github常用命令汇总
创立版本库 mkdir Baiducd Baidugit init SSHssh-keygen -t -rsa -C "TaylorApril947939@gmail"(在gith ...
- 关于log4j中log4j.properties和log4j.xml的加载顺序
如果采用log4j输出日志,要对log4j加载配置文件的过程有所了解. log4j启动时,默认会寻找source folder下的log4j.xml配置文件,若没有,会寻找log4j.properti ...
- js 原生轮播图插件
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 主成分分析(PCA)模型概述
数据降维 降维是对数据高维度特征的一种预处理方法.降维是将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的.在实际的生产和应用中,降维在一定信息损失范围内,可 ...
- makefile(3)函数
前言 学习make和makefile的主要目的是分析大型项目的源代码的关系,上一节我们讲述了makefile 中的变量,本节主要学习一下 makefile 中的函数,首先函数肯定可以分为几部分: 内置 ...
- 事件绑定持有对象引用导致GC不回收对象
现象 封装了一个部门选择框对象,在第一次创建选择框的时候是正确的,但是在关闭之后再次创建,发现点击事件被调用两次,于是console.log(),发现第一次创建的选择框的数据也被打印了一次,执行两次分 ...