默认的Racket是要对函数参数进行求值的, 例如(f 1 (+ 1 2))里面,(+ 1 2)要先求值为3,变为(f 1 3)再进行下一步操作.因此, Racket若按照SICP使用define关键字来定义延时计算的关键函数delay和cons-stream是不可行的, 需要用宏来定义,绕过求值.

#lang racket

(define (memo-proc proc)
(let ((already-run? #f) (result #f))
(lambda ()
(if already-run?
result
(begin (set! result (proc))
(set! already-run? #t)
result))))) (define-syntax-rule (delay exp)
(memo-proc (lambda () exp))) (define-syntax-rule (cons-stream a b)
(cons a (delay b)))

这里memo-proc是用于避免重复计算延时过程的. 比如首次调用延时过程(+ 1 2 3), 我们得到了结果6, 那么如果还需要反复调用它1万次, 显然再进行1万次(+ 1 2 3)的计算是不明智的,只需记住首次的结果, 以后再被调用时直接用它就可以了. 但这也说明了延时过程需要是无副作用的.

下面是其他延时函数的定义:

(define-syntax-rule (force delayed-object)
(delayed-object)) (define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream))) (define (stream-ref s n)
(if (= n )
(stream-car s)
(stream-ref (stream-cdr s) (- n )))) (define (stream-map proc s)
(if (null? s)
'()
(cons-stream (proc (stream-car s))
(stream-map proc (stream-cdr s))))) (define (stream-for-each proc s)
(if (null? s)
'done
(begin (proc (stream-car s))
(stream-for-each proc (stream-cdr s))))) (define (stream-enumerate-interval low high)
(if (> low high)
'()
(cons-stream
low
(stream-enumerate-interval (+ low ) high)))) (define (display-line x)
(newline)
(display x)) (define (display-stream s)
(stream-for-each display-line s)) (define (show x)
(display-line x)
x) ; test begins... (define x (stream-map show (stream-enumerate-interval )))
(stream-ref x )
(stream-ref x )

感慨: 其实我这里的宏只是相对于C语言里的那种文本替换宏. Racket的宏还能更加复杂. Scheme系语言的表达能力确实强悍, 但或许不太适合团队. 一是S表达式的形式繁琐, 语法简单优雅的代价就是视觉上的反人类,不利于交流. 二是这种语言可定制性太强, 你喜欢这样搞, 我还喜欢那样搞呢, 谁愿去理解你那些说不定你自己过段时间都理解不了的各种宏或延续的奇技淫巧呢.  此时对比Python, 其设计者的良苦用心可见一斑.

Racket 模拟SICP的流(延时计算)的更多相关文章

  1. 流式计算(二)-Kafka Stream

    前面说了Java8的流,这里还说流处理,既然是流,比如水流车流,肯定得有流的源头,源可以有多种,可以自建,也可以从应用端获取,今天就拿非常经典的Kafka做源头来说事,比如要来一套应用日志实时分析框架 ...

  2. Others-阿里专家强琦:流式计算的系统设计和实现

    阿里专家强琦:流式计算的系统设计和实现 更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 阿里云数据事业部强琦为大家带来题为“流式计算的系统设计与实现”的演讲,本 ...

  3. 流式计算(三)-Flink Stream 篇一

    原创文章,谢绝任何形式转载,否则追究法律责任! ​流的世界,有点乱,群雄逐鹿,流实在太多,看完这个马上又冒出一个,也不知哪个才是真正的牛,据说Flink是位重量级选手,能流计算,还能批处理, 和其他伙 ...

  4. Java的lamda表达式/函数式接口/流式计算

    在我们看他人code的时候经常会看到,可能会经常看到lambda表达式,函数式接口,以及流式计算.在刚接触这些新功能时,也觉得真的有必要吗?但是现在写多了,发现这个功能确实能简化代码结构,提升编码效率 ...

  5. 搜索广告与广告网络Demand技术-流式计算平台

    流式计算平台-Storm 我们以Storm为例来看流式计算的功能是什么. 下面内容引用自大圆的博客.在Storm中,一个实时应用的计算任务被打包作为Topology发布,这同Hadoop的MapRed ...

  6. 流式计算与计算抽象化------《Designing Data-Intensive Applications》读书笔记15

    上篇的内容,我们探讨了分布式计算中的MapReduce与批处理.所以本篇我们将继续探索分布式计算优化的相关细节,并且分析MapReduce与批处理的局限性,看看流式计算是否能给我们在分布式计算层面提供 ...

  7. Apache Beam—透视Google统一流式计算的野心

    Google是最早实践大数据的公司,目前大数据繁荣的生态很大一部分都要归功于Google最早的几篇论文,这几篇论文早就了以Hadoop为开端的整个开源大数据生态,但是很可惜的是Google内部的这些系 ...

  8. kafka 流式计算

    http://www.infoq.com/cn/articles/kafka-analysis-part-7/ Kafka设计解析(七)- 流式计算的新贵 Kafka Stream

  9. [原创] 如何PCB通流能力计算

    一.计算方法如下: 先计算Track的截面积,大部分PCB的铜箔厚度为35um(不确定的话可以问PCB厂家)它乘上线宽就是截面积,注意换算成平方毫米. 有一个电流密度经验值,为15~25安培/平方毫米 ...

随机推荐

  1. Mybatis JPA 插件简介(v2.1.0)

    相比之前的版本(v1.1.0),此版本(v2.1.0)做了较大的改动. 项目地址: github https://github.com/cnsvili/mybatis-jpa gitee https: ...

  2. Tab标签js切换高效率写法

    原来的传统写法: function tabit(id,cid) { for(var i=0; i<10; i++){ gi(["tab"+i]).className = &q ...

  3. 如何设计一款APP,才能吸引用户眼球

    有APP分析机构研究表明,人们每天耗费在手机和平板上的平均时长为158分钟,其中127分钟是耗费在各类APP中,而仅有31分钟是花费在浏览网页上.随着人们对互联网的依赖性越来越强,移动APP发展迅速已 ...

  4. 初探java对象比较

    判断两个对象的属性值是否相等的方法, class Book{ private String title; private double price; public Book(String title, ...

  5. 机器学习技法:07 Blending and Bagging

    Roadmap Motivation of Aggregation Uniform Blending Linear and Any Blending Bagging (Bootstrap Aggreg ...

  6. 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步

    学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...

  7. hdu 5441 (并查集)

    题意:给你n个点,m条边构成无向图.q个询问,每次一个值,求有多少条路,路中的边权都小于这个值 a->b 和 b->a算两种 思路:把权值从小到大排序,询问从小到大排序,如果相连则用并查集 ...

  8. SPOJ 7258 Lexicographical Substring Search

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  9. [usaco6.1.1Postal Vans]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给你一个4*n的棋盘,问从(1,1)出发恰好经过所有格子一次的走法数量.(n<=1000) 插头dp,用f[i][j][k]表示转移到第 ...

  10. A Problem-Solving FlowChart || 如何解决编程问题

    This is from book Cracking the coding interview, Gayle Laakmann Mcdowell. The flowchart can be used ...