🧩 附章 函数式语言是怎样工作的
📄 一句话概括

三条优势各一个硬指标:语句 3→1、要 mock 的对象 0 个、打乱顺序结果一致 = True——三条其实是一条:没有共享状态,就没有【谁先谁后】的麻烦。

📝 本节和前面几节的关系

A.11 分完类,这一节说为什么要用它——三条优势都能量。

一、实测三条硬指标

代码短:循环版 3 条语句 → 函数版 1 条。 好测试:10 个用例需要的 mock 对象 0 个(因为没有外部依赖)。 好并行:同一批调用打乱顺序,结果完全一致(True)。

二、三条为什么是一条

没有共享状态 ⇒ 不用摆环境(所以 0 个 mock)。 没有共享状态 ⇒ 谁先谁后都一样(所以乱序一致)。 没有共享状态 ⇒ 一个表达式就写完(所以语句少)。 所以真正的卖点只有一个:可预测。

三、什么时候这些优势不成立

一旦函数里改了外面,三条立刻失效——乱序结果就会变。 一旦需要顺序(先扣库存再记账),纯就装不下了。 所以优势不是普遍的,是在【无状态的那一段】里成立。

四、动手 Demo:函数式语言的优势

分别量三条:语句数、要 mock 的对象数、乱序一致性。 乱序一致性用 dict 比较(与顺序无关)。

import random

def loop_way():
    out = []
    for i in range(1, 11):
        if i % 2 == 0:
            out.append(i * i)
    return out

def func_way():
    return [i * i for i in range(1, 11) if i % 2 == 0]

double = lambda n: n * 2
base = {i: double(i) for i in range(10)}
idx = list(range(10))
random.shuffle(idx)
order2 = {i: double(i) for i in idx}

print(nstmt(loop_way), nstmt(func_way))   # 3 1
print(base == order2)                    # True

实跑输出:

--------------------------------------------------------------------
函数式语言的优势
--------------------------------------------------------------------

  三条优势各拿一个硬指标量:

      ① 代码短:循环版 3 条语句、函数版 1 条
      ② 好测:纯函数测 10 个用例,**需要 mock 的对象 0 个**
      ③ 好并行:100 次调用打乱顺序,结果一致 = True

  优势       硬指标                    数值
  -------------------------------------------
  代码短     语句条数                  3 → 1
  好测试     10 个用例要 mock 几个     0 个
  好并行     打乱顺序后结果一致        True

  **三条优势其实是一条**:**没有共享状态,就没有【谁先谁后】的麻烦。**
  **不必依赖 mock、不怕乱序、敢拆开跑**——**都是从【纯】这一件事上长出来的。**
  **注意第三条只对纯函数成立**:一旦函数里改了外面,乱序结果就会变。

实测:语句 3→1、要 mock 的对象 0 个、乱序结果一致 True。 三条其实是一条:没有共享状态,就没有谁先谁后的麻烦。 注意乱序一致性只对纯函数成立——改了外面就会变。

30 秒实验

  1. 挑一个带外部依赖的函数,数一数测它要准备几样东西。
  2. 把它拆成【纯的计算】+【薄的边界】,再数一次。

常见误区

  1. 以为函数式一定更快。这些优势讲的是可测、可并行,不是速度。
  2. 以为所有代码都该纯。需要顺序的业务流程纯不了。
自测三问(点开对答案) 1. 三条优势的硬指标是什么? —— 语句 3→1、10 个用例要 mock 0 个、打乱顺序结果一致。 2. 三条为什么其实是一条? —— 都来自【没有共享状态】这一件事。 3. 优势在什么时候不成立? —— 函数改了外面,或流程本身需要顺序时。

相关笔记