重新认识斐波那契与高阶抽象
Grey
全部学习汇总:https://github.com/GreyZhang/g_SICP
- 这里其实在教材之中就对我一直好奇且有一些疑问的问题给定了性:递归方式实现斐波那契函数其实有很大的研究指导意义,但是在工程实践上其实不见得是一个很好的方法。这里面有太多的计算浪费,自然也就带来了很多资源消耗。
- 那么,我好奇的其实又有了一点:递归思想的应用在什么情况下可以在工程之中使用?如果可以应用,应该满足什么样的条件?在我的嵌入式软件设计中,这个是否是一个可行的方案?
代码分析,a-b的和
(define (sum-integers a b)
(if (> a b)
0
(+ a (sum-integers (+ a 1) b))))
- 这个刚开始看的时候还愣了一下,但是其实就是非常简单的小把戏。把第一个已知的元素拆出来了而已。
(define (cube x) (* x x x))
(define (sum-cubes a b)
(if (> a b)
0
(+ (cube a) (sum-cubes (+ a 1) b))))
- 如果上面的例子能够分析得明白,其实这个也很容易理解。处理的核心点其实是在于削减参与计算的元素个数。
- 其实,这样的例子都是同样的原理。而这个应该会涉及到我们数学中的级数了,如果有类似的公式求解其实是容易的。但是,话又说回来,或许这依然不是工程最佳实现。
- 针对上面的比较有一致性的问题的处理,也就是级数的处理,其实可以有一个模板形式的处理方法。
(define (pi-sum a b)
(define (pi-term x)
(/ 1.0 (* x (+ x 2))))
(define (pi-next x)
(+ x 4))
(sum pi-term a pi-next b))
- 这是按照上面的模式重写了之前的一个函数实现,从按照这个模板的设计,整个的软件设计思路以及简洁程度的确是好了很多。
- 这样,我又有一个新的疑问了。如果我用C语言来实现,这样的方式容易实现吗?简单梳理如下:
- 首先得定义一个基础的模板处理函数,sum,返回值可能得是double能够容纳更多的类型。而两个函数接口,term可以void *增加兼容性,但是最好函数返回double。next得是返回数据为int的函数指针,ab自然还得是int。
- 实现两个不同的函数。term,按照double来设计。next,就是查找下一个规则下的b。
- 这样设计基本行得通,但是数据类型的考虑上可能欠缺周到。而且,使用的时候也会涉及到最终结果的强制数据类型转换。多少还是有点复杂化,感觉上C的设计就不该用这种复杂化的路子,这样的设计多少还是适合类似python这样的若类型检查的语言的。
- 关于lambda的使用,不得不说,在这里我是第一次get到了lambda的灵活好用!
- 曾经还用C语言中的内联函数来与之对比,现在看来这个绝对不是内联函数那么简单。
- 这里,我可能得到了一个类似读懂C语言指针一样的公式秘诀了!
这一次的学习,跳过了很多具体内容的分析。看起来,现在MIT最新的python的6周课程其实就是这个课程的一个替代品,但是从表达效果上来说,lisp相比python的表达的确是自由得多。