主要参考:

http://www.shido.info/lisp/scheme7_e.html

Function fact that calculates factorials.

(define (fact n)
(if (= n 1)
1
(* n (fact (- n 1)))))

(fact 5) is calculated like as follows:

(fact 5)
⇒ 5 * (fact 4)
⇒ 5 * 4 * (fact 3)
⇒ 5 * 4 * 3 * (fact 2)
⇒ 5 * 4 * 3 * 2 * (fact 1)
⇒ 5 * 4 * 3 * 2 * 1
⇒ 5 * 4 * 3 * 2
⇒ 5 * 4 * 6
⇒ 5 * 24
⇒ 120

(fact 5) calls (fact 4)(fact 4) calls (fact 3), then finally (fact 1) is called. (fact 5)(fact 4) ,.., and (fact 1) are allocated at different memory spaces and(fact i) stays there until (fact (- i 1)) returns a value, which wastes the memory space and takes more calculation time because of the overhead of function call.

However, recursive functions can express repetition in a simple manner. Further as lists are defined recursively, lists and recursive functions fit together. For instance, a function that makes all list items twice is defined like as follows. The function should return an empty list if the argument is an empty list to terminate the calculation.

(define (list*2 ls)
(if (null? ls)
'()
(cons (* 2 (car ls))
(list*2 (cdr ls)))))

3. Tail Recursive

Ordinary recursive function is not efficient because of wasting memory and function call overhead. On the contrary, tail recursive functions include the result as argument and returns it directory when the calculation finishes. Especially, as Scheme specification requires conversion of a tail recursive to a loop, there is no function call overhead.

[code 2] shows a tail recursive version of function fact shown in [code 1].

[code 2] fact-tail, tail recursive version of fact

(define (fact-tail n)
(fact-rec n n)) (define (fact-rec n p)
(if (= n 1)
p
(let ((m (- n 1)))
(fact-rec m (* p m)))))
fact-tail calculates factorial like as follows:
(fact-tail 5)
⇒ (fact-rec 5 5)
⇒ (fact-rec 4 20)
⇒ (fact-rec 3 60)
⇒ (fact-rec 2 120)
⇒ (fact-rec 1 120)
⇒ 120
As fact-rec does not wait the result of other functions, it disappears from the memory space when it finishes. The calculation proceeds by changing argument of fact-rec, which is basically the same as loop. As mentioned previously, as Scheme convert a tail recursive to a loop, Scheme can do repetition without syntax for looping.

4. Named let

The named let is available to express loop. [code 3] shows a function fact-let that calculates factorials using named let. The fact-let uses a named let expression (loop), instead of fact-rec shown in [code 2]. First it initializes parameters (n1p) with n at the line marked with ; 1. These parameters are updated at the line marked with ; 2 after each cycle: Subtracting n1 by one and multiplying p by (n1-1)

A named let is a conventional way to express loops in Scheme.

[code 3]

(define (fact-let n)
(let loop((n1 n) (p n)) ; 1
(if (= n1 1)
p
(let ((m (- n1 1)))
(loop m (* p m)))))) ; 2

5. letrec

While it is similar to the named let, a name defined by letrec can refer itself in its definition. The letrec syntax is used to define complicated recursive functions. [code 4] shows a letrec version of fact.

[code 4]

(define (fact-letrec n)
(letrec ((iter (lambda (n1 p)
(if (= n1 1)
p
(let ((m (- n1 1)))
(iter m (* p m))))))) ; *
(iter n n)))
As shown at the line of ; *, the local variable iter can refer itself in the definition of iter. Syntax letrec is a conventional way to define local functions.

scheme递归的更多相关文章

  1. Teach Yourself Scheme in Fixnum Days 6 recursion递归

    A procedure body can contain calls to other procedures, not least itself: (define factorial (lambda ...

  2. Scheme中一些函数在C++里面的实现与吐槽

          最终我失败了,这是显而意见,我试图在一个很看重类型是什么的语言中实现无类型操作,事实上,哪怕我实现了基本的cons,car,cdr,list后面的代码也无法写下去.比如说list-n,根据 ...

  3. 与Scheme共舞

    发表在<程序猿>2007年7月刊上.不log上写帖子不用考虑版面限制,所以这里的帖子比发表的啰嗦点.赵健平编辑,Jacky,和刘未鹏都给了我非常多帮助,在这里一并谢了.免费的Scheme实 ...

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

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

  5. MIT scheme入门使用

    在win7下可安装MIT-GUN scheme, 点开后有两个界面:一个交互式命令行界面:一个Edwin界面.    在命令行界面按Ctrl-G可以开始输入.在Edwin界面,输入完整命令后按Ctrl ...

  6. scheme Continuation

    Continuation Pass Style在函数式编程(FP)中有一种被称为Continuation Passing Style(CPS)的风格.在这种风格的背后所蕴含的思想就是将处理中可变的一部 ...

  7. 递归——CPS(一)

    程序中为什么需要栈stack? 普通的程序中,接触到子程序和函数的概念,很直观地,调用子程序时,会首先停止当前做的事情,转而执行被调用的子程序,等子程序执行完成后,再捡起之前挂起的程序,这有可能会使用 ...

  8. Scheme实现二叉查找树及基本操作(添加、删除、并、交)

    表转化成平衡二叉树 其中有一种分治的思想. (define (list->tree elements) (define (partial-tree elts n) (if (= n 0) (co ...

  9. Scheme r5rs letrec的用法

    说明,这是r5rs的用法. (letrec ((<variable> <init>) ...) <body>) 假设((<variable> <i ...

随机推荐

  1. HighCharts去掉水印链接

    找到highcharts-all.js文件,将credits:{enabled:!0}改为credits:{enabled:0}即可

  2. poj 3498 March of the Penguins(最大流+拆点)

    题目大意:在南极生活着一些企鹅,这些企鹅站在一些冰块上,现在要让这些企鹅都跳到同一个冰块上.但是企鹅有最大的跳跃距离,每只企鹅从冰块上跳走时会给冰块造成损害,因此企鹅跳离每个冰块都有次数限制.找出企鹅 ...

  3. HDOJ-1019 Least Common Multiple

    http://acm.hdu.edu.cn/showproblem.php?pid=1019 题意:给出n个数,求它们的最小公倍数 对于n个数,它们的最小公倍数等于[前n-1个数的最小公倍数和第n个数 ...

  4. poj 2305(指定进制,大数取模)

    题意:输入一个进制b,在输入两个基于b进制的大整数 x,y ,求x%y的b进制结果. http://162.105.81.212/JudgeOnline/problem?id=2305 函数: Str ...

  5. python高级编程之最佳实践,描述符与属性01

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #最佳实践 """ 为了避免前面所有的 ...

  6. (转)Tomcat 7 访问 Manager 和 Host Manager

    配置好 Tomcat 7.0 后,在 tomcat-users.xml 中配置用户角色来访问 localhost:8080 的这样三个按钮总出现问题: Server Status Manager Ap ...

  7. [Immutable.js] Exploring Sequences and Range() in Immutable.js

    Understanding Immutable.js's Map() and List() structures will likely take you as far as you want to ...

  8. Swift基础--使用TableViewController自定义列表

    首先建立一个swift项目,把storyboard的内容删掉,添加一个 Navigation Controller,然后设置storyboard对应界面的class,在Navigation Contr ...

  9. html5 video播放不全屏

    <video controls="controls" webkit-playsinline src="${page.videoUrl }" type=&q ...

  10. [Python学习笔记][第四章Python字符串]

    2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...