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

同一件事,匿名类写法 12 行、lambda 写法 4 行,结果都是 [4, 6, 9, -3]——Java 改不了语法,就在语言里圈出一小块地,让函数式在那儿按自己的规矩跑。

📝 本节和前面几节的关系

A.15 讲完怎么上手,这篇专栏用一个具体例子收束:主流语言是怎么把函数式装进来的。

一、实测:12 行压到 4 行

四个小类(加一、乘二、平方、取负),每个 3 行,共 12 行。 四个 lambda,一行一个,共 4 行。 两种写法跑出来的结果完全一致:[4, 6, 9, -3]。 省下的 8 行不是重点,重点是【不用为一次性的做法起名字】。

二、什么叫【箱庭】

箱庭=在自家院子里搭的小院:地方不大,但里面按另一套规矩运转。 Java 不能改自己的语法——类是它唯一的组织单位。 于是它圈出一小块地(lambda+Stream),在那里函数可以当值传。 出了这块地,还是老规矩。

三、为什么这个词很准

不是搬来一个新世界——Java 没有变成 Haskell。 是搭了个小院——能做的有限,但够用。 这也是所有主流语言的做法:C# 有 LINQ、Python 有推导式、JavaScript 有箭头函数。 都是箱庭,都不是新世界。

四、动手 Demo:打造了函数式语言的箱庭的Java

同一件事写两版:四个小类 对 四个 lambda。 量行数并确认结果一致。

class AddOne:
    def apply(self, x):
        return x + 1

class Double:
    def apply(self, x):
        return x * 2

klass = [AddOne(), Double()]
lams = [lambda x: x + 1, lambda x: x * 2]

print([k.apply(3) for k in klass])   # [4, 6]
print([f(3) for f in lams])          # [4, 6]

实跑输出:

--------------------------------------------------------------------
打造了函数式语言的箱庭的Java
--------------------------------------------------------------------

  专栏说 Java 里搭了个【箱庭】让函数式跑起来。**量化【有 lambda 前后】的写法差:**

  写法            形态                     行数
  ----------------------------------------------
  匿名类写法      四个类,每个 2~3 行     12
  lambda 写法     四个表达式,一行一个     4

      两种写法结果一致            True(都是 [4, 6, 9, -3])
      行数比                      12 : 4
      少了多少                    8 行

  **同一件事从 12 行压到 4 行**——**这就是那层【箱庭】的作用:把函数装成值。**
  **Java 不能改自己的语法**,于是在语言里圈出一小块地(lambda+Stream),
  **让函数式在那儿按它自己的规矩跑。**
  **所以【箱庭】这个词很准**:**不是搬来一个新世界,是在自家院子里搭了个小院。**

实测:四个小类 12 行、四个 lambda 4 行,结果都是 [4, 6, 9, -3]。 箱庭=自家院子里的小院:地方不大,里面按另一套规矩运转。 C# 的 LINQ、Python 的推导式、JS 的箭头函数都是箱庭,都不是新世界。

30 秒实验

  1. 列一下你常用语言里那层【箱庭】在哪:哪些写法是【函数式入口】?
  2. 试一次在箱庭外沿用它的规矩(例如把状态也塞进 lambda),看会不会别扭。

常见误区

  1. 以为加了 lambda 就是函数式语言。那只是开了个门。
  2. 以为箱庭小就没价值。够用比纯粹重要。
自测三问(点开对答案) 1. 两版行数与结果各是多少? —— 匿名类 12 行、lambda 4 行,结果都是 [4, 6, 9, -3]。 2. 箱庭指什么? —— 语言里圈出的一小块地,在那里函数可以当值传,其余仍按老规矩。 3. 还有哪些语言有箱庭? —— C# 的 LINQ、Python 的推导式、JavaScript 的箭头函数。

相关笔记