📄 一句话概括
按副作用分三类:纯函数式只剩 Haskell 一门死守,非纯 4 门、混合 4 门——这不是谁不纯粹,是工程现实:程序总要读写文件、总要有顺序。
📝 本节和前面几节的关系
A.10 打完分,这一节把语言按副作用分成三类,看清主流在哪一类。
一、实测:三类九门语言
纯函数式:Haskell(不允许副作用),只剩 1 门。 非纯函数式:OCaml/F#/Clojure/Erlang(允许但少用),4 门。 混合:Python/Java/C#/JavaScript(随便用),4 门。 九门里只有一门死守纯净。
二、为什么不纯的才是多数
程序总要和外界打交道:读文件、打日志、发请求、按顺序执行。 纯函数式用【单子】这类东西把这部分圈起来,概念门槛由此而来。 混合语言的选择:不圈,靠自觉——代价是编译器帮不了你。
三、怎么用这个分类
选语言:业务系统几乎都在第三类,因为要干活。 学语言:想体会纯函数式,去写两星期 Haskell,比读十篇文章有用。 写代码:不管哪类,都可以在局部用纯函数——这才是最实用的结论。
四、动手 Demo:函数式语言的分类
按副作用分三类,各列代表语言。 数一数【完全不同副作用】的有几门。
rows = [("纯函数式", "Haskell", "不允许", 1),
("非纯函数式", "OCaml/F#/Clojure/Erlang", "允许但少用", 4),
("混合", "Python/Java/C#/JavaScript", "随便用", 4)]
print(len(rows), sum(n for a, b, c, n in rows)) # 3 9
print(sum(n for a, b, c, n in rows if c == "不允许")) # 1
实跑输出:
--------------------------------------------------------------------
函数式语言的分类
--------------------------------------------------------------------
按【允许不允许副作用】分三类,**每一类举几个真实语言:**
类别 代表语言 副作用 语言数
----------------------------------------------------------------------
纯函数式 Haskell 不允许 1
非纯函数式 OCaml/F#/Clojure/Erlang 允许但少用 4
混合 Python/Java/C#/JavaScript 随便用 4
类别 3 类
列出的语言 9 门
【完全不许副作用】的语言 只有 1 门(Haskell)
**纯函数式只剩 Haskell 一门死守**,**其余全是妥协版本。**
**这不是谁不纯粹,是工程现实**:程序总要读写文件、总要打印、总要有顺序。
**所以主流是第三类**——**把函数式的手法装进一门能干活的通用语言里。**
实测:三类九门语言,死守纯净的只有 1 门(Haskell)。 不纯的才是多数,因为程序总要读写文件、总要有顺序。 最实用的结论:不管用哪类语言,都可以在局部写纯函数。
30 秒实验
- 查一下你常用语言里哪几样东西天生不纯(文件、时间、随机数、日志)。
- 试着把它们集中到一个薄薄的边界层里,其余部分尽量纯。
常见误区
- 以为非纯就是妥协、就是差。工程语言都是妥协出来的。
- 以为必须改用纯函数式语言才能享受到好处。局部写纯函数就够。
自测三问(点开对答案)
1. 三类各是什么? —— 纯函数式(Haskell)、非纯函数式(OCaml/F#/Clojure/Erlang)、混合(Python/Java/C#/JavaScript)。 2. 为什么纯函数式语言这么少? —— 程序必须与外界打交道,纯要把这部分圈起来,概念代价高。 3. 最实用的结论是什么? —— 不管用哪类语言,都能在局部写纯函数。- ☐ A.12 函数式语言的优势
相关笔记
- 对7个特征的总结 — 打分版
- 函数式语言的优势 — 接着讲好处
- 特征5:没有副作用 — 分类的依据
- 🧩 面向对象是怎样工作的 · 索引