Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1695044
  • 博文数量: 177
  • 博客积分: 9416
  • 博客等级: 中将
  • 技术积分: 2513
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-06 16:08
文章分类

全部博文(177)

文章存档

2013年(4)

2012年(13)

2011年(9)

2010年(71)

2009年(12)

2008年(11)

2007年(32)

2006年(25)

分类: Python/Ruby

2012-06-01 13:43:33

经过了三个月左右的集中学习(intensive learning),终于可以使用Scheme做一些简单的工作了,而且,也能够依葫芦画瓢做一些复杂点的工作了——然而,用Scheme语言编程,其重点是如何找到解决问题的方法,而不是如何去实现这个解决方法,因为Scheme提供了很强的表达能力,将程序员们从语言的细节以及语法糖蜜中解放出来,使得他们能够更专注于问题本身,而不是实现本身。
  • 起步
回想起自己接触、学习函数式变成和Scheme的经过,其中充满了曲折和坎坷。Scheme语言本身的简单性导致了其灵活性,使得一个人可以在几天之内学完基本语法,但要使用好Scheme,需要长时间的训练。另外,对于初学者来说一个难点就是Lisp方言太多,而每个方言的各种实现也不尽相同,这就导致了在真正开始学习之前需要选择一个合适的Scheme实现。

在2008年年底的时候,因为跟cuigang讨论一个C++的问题,开始知道函数式编程范式,于是买了本《》(SICP)开始了Scheme之旅。然而,一方面函数式语言确实不符合自己一贯的编程习惯,另一方面这本书更注重数学方面,因此,开始的学习历程很艰苦,不但无法熟练使用尾递归,加之工作负载确实不小,于是便放弃了。
  • 重拾Scheme
那是在将近三年以后了。在2011年年中,因为公司战略调整,手里基本上没有什么工作了。在某天整理书架时发现了SICP书,于是又开始学习了。这里必须承认,我看书的习惯确实不好,因为不能先浏览几遍,再开始精读。入门的艰苦导致了又产生了放弃的念头,此时无意之中发现了《》,号称SICP的基础。这本书确实不算太难,话了很大的篇幅来讲述递归和尾递归,并提供了大量的基础练习。通过结合“循环不变式”的知识,并浏览了一些Scheme的语言构造之后,终于能够用尾递归来解决问题了。那段时间为了理解尾递归并解答相关的习题,经常在快睡着时突然有了思路,于是起来上机调试。在Simply Scheme系列的(2)、(3)、(4)中可以看到这些习题。在学习了do、loop和命名let之后,突然间好像醍醐灌顶,便有了这一篇:[原]重新开始学习Scheme(2):线性递归以及循环不变式。根据循环不变式,我们就可以很轻松地用尾递归来解决这两个问题:
1. 当n<3时,f(n)=n;否则,f(n) = f(n-1)+2f(n-2)+3f(n-3)。代码如下:
  1. (define (f-i n)
  2.   (let iter ((fn 4) (fn-1 2) (fn-2 1) (fn-3 0) (i n))
  3.     (cond ((< n 3) n)
  4.           ((= i 3) fn)
  5.           (else
  6.            (iter (+ fn (* 2 fn-1) (* 3 fn-2))
  7.                  fn
  8.                  fn-1
  9.                  fn-2
  10.                  (- i 1))))))
2. 求解1!+2!+3!+...+n!。代码如下:
  1. (define (fac-sum n)
  2.   (let iter ((fi-1 1) (c 1) (r 0))
  3.     (if (= c (+ n 1)) r
  4.         (iter (* fi-1 c) (+ c 1) (+ r (* fi-1 c))))))
  • 为了工作而学习Scheme
快乐的日子总是短暂的。还没有完成Simply Scheme的一半,工作强度又大了起来,于是,Scheme的学习又放下了,直到工作中切切实实需要用到Scheme。正如我在“[原]重新开始学习Scheme(1)”中所说的,出于兴趣和工作需要来学习某项技能,其过程和结果都是不一样的,各有长短吧。如果不是项目需要,我也不可能在这么短的时间内如此高密度地学习一项技能;但正因为项目需要,不可能花大量的时间在自己的兴趣点上,这样就导致了许多问题遗留下来。因此,虽然在“重新开始学习Scheme”系列里涵盖了Scheme的几个重要特性,但好像除了尾递归,其他的特性我都只是摸到,甚至只是刚看到门槛而已。幸好工作中使用这些特性的机会不多,因此还是可以自诩为Scheme工程师。Scheme程序员?按照Lisp社区的说法,必须要能够写一个Lisp解释器,才能自称为Lisp程序员。这话同样适合于Scheme。

在这样一家公司,由于战略调整和重组是非常频繁的事情,现在虽然开始做Scheme相关的工作,但恐怕过不了多久又会被安排去做其他的东西,那后续的Scheme学习就会成为镜花水月——但愿不要再在我身上发生这样的事情了。
  • 书目
《》:函数式编程和Scheme的入门教材。正如王垠所说,这本书只有前三章对于初学者有价值。
《》:虽然SICP的作者认为这本书的作者在恭维SICP,但确实难度要低一些。
《》:虽然是CL方言,但可以让读者对FP和Lisp有个大概的认识
《》:高质量的一本书,里面一些重要章节同样适用于Scheme和CL,例如关于continuation的说明。
《》:不多说了,估计地位跟TCPL之类的书差不多。
还有很多其他的书,这里不一一列举。
  • 参考资料
:Scheme的一个实现,提供全面的文档和图形库
:Scheme社区
:论文聚合点
"Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I":关于FP和Lisp的开山之作
"Why Functional Programming"
  • 真的可以说学会了,不用再学习了吗?
虽然只是刚刚具备了Scheme的基础,但系统学习这一阶段确实可以结束了,毕竟,项目就在那里,公司也不可能永远让员工处于学习状态,只向员工投入资金而不向员工要产出的公司只能出现在梦里。因此,以后基本不会有大量时间来集中学习Scheme了。我想,是时候总结一下了。——以后随用随学,一次一个小知识点。
阅读(8130) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~