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

Python 里能当表达式用的 4 种、只能当语句的 3 种——if/for/赋值本身还是语句;真正的函数式语言里没有【语句】这个东西。

📝 本节和前面几节的关系

A.3 讲不写名字,这一节讲为什么能直接嵌进任何位置——因为它们本身就是一个值。

一、实测:哪些能放赋值右边

能:1 + 2、a if c else b、[i*i for i in range(3)]、(lambda x: x+1)(2)。 不能:if c: x = 1、for i in x: pass、x = 1(都报语法错误)。 所以 Python 只做到一半:三元与推导式是表达式,if/for/赋值还是语句。

二、没有语句意味着什么

整段程序就是一个大表达式——每一层都能被上一层当参数吃进去。 这就是为什么函数式代码能自然组合:没有【只能单独占一行】的东西。 反过来看也有代价:没有语句就少了【先做这个、再做那个】的直白写法。

三、实际怎么用

能写成表达式的地方就别写语句:x = a if c else b 比 if/else 两行更紧。 推导式代替 append 循环:3 条语句变 1 条。 但别硬套:一段有 4 个步骤的流程,写成一条嵌套表达式就是灾难。

四、动手 Demo:特征2:所有表达式都返回值

列 4 种能当表达式的写法、3 种只能当语句的写法。 两种各数几个。

ok = ["1 + 2", "a if c else b", "[i*i for i in range(3)]",
      "(lambda x: x + 1)(2)"]
bad = ["if c: x = 1", "for i in x: pass", "x = 1"]

print(len(ok), len(bad))       # 4 3

try:
    compile("x = if True: 1", "<s>", "exec")
except SyntaxError as e:
    print(type(e).__name__)    # SyntaxError

实跑输出:

--------------------------------------------------------------------
特征2:所有表达式都返回值
--------------------------------------------------------------------

  【都是表达式】意味着**每一样东西都能放进赋值右边**。实测 Python 里哪些能、哪些不能:

  写成赋值右边                结果
  -------------------------------------
  1 + 2                       有值
  a if c else b               有值
  [i*i for i in range(3)]     有值
  (lambda x: x + 1)(2)        有值
  if c: x = 1                 语法错误
  for i in x: pass            语法错误
  x = 1                       语法错误

      能当表达式用的              4 个
      只能当语句的                3 个

  **Python 只做到一半**:三元写法和推导式是表达式,**`if`/`for`/赋值本身还是语句。**
  **真正的函数式语言里没有【语句】这个东西**——**整段程序就是一个大表达式。**
  **这就是为什么函数式代码能自然地嵌进任何位置**:它没有【只能单独占一行】的东西。

实测:能当表达式 4 种、只能当语句 3 种,x = if True: 1 直接语法错误。 真正的函数式语言没有【语句】,整段程序就是一个大表达式。 这就是函数式代码能随便嵌进任何位置的根因。

30 秒实验

  1. 把一段 if/else 赋值改成三元表达式,行数能少几行?
  2. 再把一段三层嵌套的表达式拆回语句,看看可读性是不是反而更好。

常见误区

  1. 以为【都是表达式】只是语法糖。它决定了代码能不能被组合。
  2. 把长流程压成一条表达式。那不是函数式,那叫没法调试。
自测三问(点开对答案) 1. Python 里哪些不能当表达式? —— if、for、赋值语句(放赋值右边直接报语法错误)。 2. 为什么函数式代码能随便嵌? —— 因为它没有语句,每一样东西本身就是一个值。 3. 表达式化的代价? —— 少了先做这个再做那个的直白写法,长流程会变得难读。

相关笔记