一、整数平方
函数式编程语言中的变量是不可变的。
二、不可变性与软件架构
为什么不可变性是软件架构设计需要考虑的重点呢?为什么软件架构师要操心变量的可变性呢?
答案显而易见:所有的竞争问题、死锁问题、并发更新问题都是由可变变量导致的。如果变量永远不会被更改,那就不可能产生竞争或者并发更新问题。如果锁状态是不可变的,那就永远不会产生死锁问题。
换句话说,一切并发应用遇到的问题,一切由于使用多线程、多处理器而引起的问题,如果没有可变变量的话都不可能变化。
三、可变性的隔离
一种常见方式是将应用程序,或者是应用程序的内部服务进行拆分,划分为可变的和不可变的两种组件。
不可变组件用纯函数的方式来执行任务,期间不更改任何状态。
这些不可变的组件将通过与一个或多个非函数式组件通信的方式来修改变量状态。
由于状态的修改会导致一系列并发问题的产生,所以我们通常会采用某种事务型内存来保护可变变量,避免同步更新和竞争状态的发生。
事务型内存基本上与数据库保护磁盘数据的方式类似,通常采用事务或者重试机制。
一个架构设计良好的应用程序应该将状态修改的部分和不需要修改状态的部分隔离成单独的组件,然后用合适的机制来保护可变量。
软件架构师应该着力于将大部分处理逻辑都归于不可变组件中,可变状态组件的逻辑应该越少越好。
四、事件溯源
随着存储和处理能力的大幅进步,现在拥有每秒可以执行数十亿条指令的处理器,以及数十亿字节内存的计算机已经很常见了。而内存越大,处理速度越快,我们对可变状态的依赖就会越少。
五、小结
- 结构化编程是对程序控制权的直接转移的限制
- 面向对象是对程序控制权的间接转移的限制
- 函数式编程是对程序中赋值操作的限制
这三个范式都对程序员提出了新的限制。每个范式都约束了某种编写代码的方式,没有一个编程范式是在增加新能力。
软件构建并不是一个迅速前进的技术。今天构建软件的规则和1946年阿兰.图灵写下电子计算机的第一行代码时是一样的。尽管工具变化了,硬件变化了,但是软件编程的核心没有变。
总而言之,软件,或者说计算机程序无一例外是由顺序结构、分支结构、循环结构和间接转移这几种行为组合而成,无可增加,也缺一不可。