大学时读了不少函数式的资料,十分喜欢函数式的风格。
前段时间比较认真地学了一下Scheme。
尽管我们在实际项目中很少会用到Scheme,但学习Scheme有助于写出更高质量函数。就像学习Smalltalk有助于理解对象。
Scheme和Smalltalk是我见过最纯粹优美的两门语言。
说说学习Scheme中的一些心得体会:

  • 表达你的意图,而不是操作过程,这样有助于我们能站在更高的抽象层面上
  • 尽量不要副作用,函数主要目的是返回(return)一个值。这样可以保证函树能更容易被当作黑箱,就是说有更好的抽象性
  • for-loops表达的是过程,map,reduce,filter(sorted,groupby)隐含循环,语义上却在表达意图
  • 表达出你的意图能提高代码可读性
  • 在自己的定义中调用自己的函数叫做递归函数.
  • 现实中很多任务是递归的,重复某个动作,符合条件退出。这是普适性很强的抽象模型
    • 以下内容有助于你理解递归:你可能需要去阅读你正在阅读的文献所引用的文献。进一步,你可能还需要去阅读文件所引用的其它文献。这样,文献调研就是一个递归的过程,你也可以重复这个调研过程直到满足了特定条件
  • 递归耗内存的原因是开销大的原因在于过程没有被计算。一直存在内存中。尾递归的本质是用某个内存空间来收集计算的结果,而不必一直存在内存中
  • cons 负责把每个结果串起来。大脑的内存不很大,我们能应付的复杂度很有限。所以每次不要走太远,每次只处理当前一步,思考后续一致,用递归的方式思考。 使用抽象来描述,不要把所有过程加载到大脑
  • 命名递归变量很重要,表达出意图
  • lambda表达式的参数仅在函数定义内部有效。let只是lambda的语法糖,因此二者无异。对于语义的表达有帮助的话,语法糖就是良好的
  • lambda表达式用于定义函数,它为变量建立了一个作用域,变量的作用域被限定在了源码中定义其的那个括号里
  • 闭包能记住内部状态,因此可以用来模拟对象
  • 赋值改变了参数的值,具有破坏性,当万不得已时才使用赋值
  • Scheme并没有定义块结构的语法,因此使用lambda表达式作为一个块
  • 高阶函数是一种以函数为参数的函数。它们都被用于映射(mapping)、过滤(filtering)、归档(folding)和排序(sorting)表。高阶函数提高了程序的模块性。使用一个高阶函数来实现排序可以使得我们使用不同的条件来排序,这就将排序条件和排序过程清楚地划分开来。很容易写函数来实现插拔。
  • Scheme中代码即数据,因此你可以通过将函数当作参数传递轻松的定义自己的高阶函数。
  • 你可以通过“程序”来写程序
  • lisp中所有东西都是数据 代码也是 虚虚实实 惰性求值变得容易 。
  • 字符是个比较关键的概念,代码本身只是文本而已。Lisp语言的最初目的就是符号处理,在Scheme语言中几乎所有的东西都可以看做是符号或做为符号列表来处理

##参考资料 * Scheme入门教程 * Scheme简明教程 * ibm