走进函数式编程 (Becomming Functional) (递归)

阅读完递归这一章我仍然无法理解递归为何被作为函数式编程的一个特性。只是递归有时候会简洁,但没弄好却更让人犯迷糊,用循环的话就四平八稳,总是比较好理解。当然有些情况用循环去思考确实难于处理。递归方法内部调用方法本身通常也比较慢,因为需要频繁的保存现场,创建栈帧,恢复现场,所以受内存限制,递归到达一定深度容易导致堆栈溢出。

章中还说到递归的一个优点在于它只需处理输入的值,而循环则需关注整个集合本身。这个该如何理解呢?在每一次递归调用的时候传入的都是当前需要被处理的数据。

先来比较下循环变换成递归的一个简单示例,用 Scala 实现 阅读全文 >>

类别: Functional. 标签: , . 阅读(55). 评论(0) »

走进函数式编程 (Becomming Functional) (2)

函数式编程第二式,纯函数 (Pure Functions). 何谓纯函数,纯函数就是数据库的函数一样没有副作用,不修改对象的内部状态,或者说只进行计算。给定什么输入,永远得到相同的输出,即输出只依赖于输入

纯函数有什么好处呢?极其容易测试,只需要给定一组输入,对输出进行断言。如果是带副作用的方法,它修改了某个私有的属性,很难进行状态判定。

Scala 基于统一访问原则,属性与方法不需要那么明晰,所以属性与方法名是不能重名的。它对有无副作用存在这么一个约定:

空括号方法 (empty-paren method), 如 def width() {...} 它是有副作的。这样调用 obj.width()
无参方法 (parameterless method), 如 def width {...}, 它是无副作的。这样调用 obj.width, 这和使用属性一致形式

Java 也有类似的约定,get 开头的或 getter 方法往往是无副作用的。要是有人偏偏在 getName() 方法里修改了对像的属性而引入了 Bug,那只会让人唏嘘不已。

方法的副作用一般有哪些呢?

  1. 输出内容到屏幕
  2. 写数据到文件或数据库
  3. 修改了对象的属性

阅读全文 >>

类别: Functional. 标签: , . 阅读(92). 评论(0) »

走进函数式编程 (Becomming Functional) (1)

本人正在阅读 《Becoming Functional》这本书,且对 Scala 的使用经验已有数年,所以品读的同时更是对头脑中函数编程的概念进行重新整理。函数编程并非一定要诸多语言特性的支持,它是一种不同的思维方式;比如说我们公司项目如今还是用的 Java 7,但我们一直以函数式思维来书写我们的代码。我们正在从 Java 7 升级到 Java 8,待到 Java 8 时代码行文肯定要比现在简练的多,但函数式编程思维未变。

下面是函数式编程基本概念

  1. First-class functions: 函数是第一类型
  2. Pure functions:  纯函数,无边界效应,输出依赖于输入,易测试。像数据库的函数而非存储过程
  3. Recursion: 递归,Scala 强调尾递归优化,避免坠入 StackOverflow
  4. Immutable variables: 这在 OO 里也是一种不错的模式,它与 Pure function 也是相辅的。可能是首先映入函数式编程思维的概念,它不关乎并发性能,解决了并发冲突
  5. Nostrict evaluation: 即变量值的赖加载,变量不到用时不初始化。在 Java 只能用方法来模拟实现
  6. Statements: 表达式优于控制结构,语句可以有返回值的,如 val a = if (condition) 1 else 2
  7. Pattern Matching: 模式匹配,不光是通常对数值或字符串的 switch/case, 还能应用到任何对象的匹配,进行类型检查或从对象中提取元素

 

Becoming Functional》逐章对上面七大概念进行讲解.

First-class functions: 函数是第一类型 阅读全文 >>

类别: Functional. 标签: , . 阅读(94). 评论(0) »