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 ...
 
随机推荐
- MOOC(10)- 获取响应中的cookie
 - 吴裕雄--天生自然 HADOOP大数据分布式处理:安装配置Tomcat服务器
			
下载链接:https://tomcat.apache.org/download-80.cgi tar -zxvf apache-tomcat-8.5.42.tar.gz -C /usr/local/s ...
 - 作业:for循环,迭代法和穷举法
			
for()循环 四要素:初始条件,循环条件,状态改变,循环体. 执行过程:初始条件--循环条件--循环体 ...
 - 可用倍增LCA解题
			
http://codevs.cn/problem/2370/ #include<bits/stdc++.h> using namespace std; ; ; struct node{ i ...
 - Win7如何查看nvidia显卡(GPU)的利用率
			
1.在文件夹C:\Program Files\NVIDIA Corporation\NVSMI里找到文件nvidia-smi.exe2.把该文件拖到命令提示符窗口(win+R,再输入‘CMD’进入), ...
 - bootstrap实现多选项及回显
			
1.前端 <link rel="stylesheet" href="${ctxStatic}/js/bootstrap-select-1.12.2/dist/css ...
 - QT "debugger unknow type"问题解决办法
			
windows上使用qt编译有两种,一种是vs的编译器,一种是MinGW的. 这种问题主要是发生在选择了MSVC2013编译器的版本,这个版本的qt需要再装一个调试器,而MinGW不用. 解决办法:下 ...
 - CF-1114C-Trailing Loves (or L'oeufs?)
			
题意: 输入n和m,求n!转换成m进制之后末尾有多少个0: 思路: 转换一下题意就可以看成,将n表示成x * (m ^ y),求y的最大值.^表示次方而不是异或: 这就比较好想了,将m分解质因数,对于 ...
 - [Redis] Redis哨兵模式部署 - zz胖的博客
			
1. 部署Redis集群 redis的安装及配置参考[redis部署] 本文以创建一主二从的集群为例. 1.1 部署与配置 先创建sentinel目录,在该目录下创建8000,8001,8002三个以 ...
 - 吴裕雄--天生自然 R语言开发学习:功效分析
			
#----------------------------------------# # R in Action (2nd ed): Chapter 10 # # Power analysis # # ...