首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >我为什么两次放弃了函数式编程,却依然感谢它

我为什么两次放弃了函数式编程,却依然感谢它

原创
作者头像
用户11680974
发布2025-08-25 17:49:51
发布2025-08-25 17:49:51
2880
举报

函数式编程到底值得学吗?为什么很多人尝试之后半途而废?undefined我自己就放弃过两次。但回头看,这两次“失败”,反而成了我编程路上的重要财富。

* * *

一、第一次邂逅:Haskell 的幻觉与崩塌

我写 Python 已经三年多了,习惯了简洁优雅的语法,也喜欢那种“写出来就能跑”的直接。

但总能在社区里听到一种声音:

函数式编程(FP)才是真正的优雅。undefined它纯粹、它无 bug,它能改变你写代码的方式。

于是,我挑了最“纯”的语言——Haskell

我的预期:

  • 写代码像写数学公式一样干净。
  • 没有混乱的状态,没有难以追踪的 bug。
  • 优雅、学术、前沿。

现实:

  • “Hello World” 都写得磕磕绊绊。
  • 我必须搞懂 Monad 才能在屏幕上输出一句话。
  • 想用循环?对不起,Haskell 里没有循环,只有递归、mapfoldr

举个例子,在 Python 里写个问候:

代码语言:txt
复制
def greet(name):
    print(f"Hello, {name}")

而在 Haskell 里,我不得不写成:

代码语言:txt
复制
main = do
  putStrLn "Enter your name:"
  name <- getLine
  putStrLn ("Hello, " ++ name)

为了理解这几行,我还得先啃一堆抽象概念:monad、IO、纯函数与副作用。

结果就是——我写了两周,还没能搭出一个能跑的项目。

我感觉自己不是在学写代码,而是在读一门数学系的高等代数课。

于是,第一次放弃

我告诉自己:“也许函数式编程不适合我。”

* * *

二、第二次尝试:Elixir 的希望与崩溃

半年后,我不甘心,又决定再给 FP 一次机会。

这次的对象是 Elixir

为什么是它?

  • 语法比 Haskell 亲民。
  • 运行在 Erlang VM 上,强调并发与容错。
  • 听说很多公司真的在用,尤其是电信、消息服务。

刚上手的时候,我很喜欢它:

代码语言:txt
复制
defmodule Greet do
  def hello(name) do
    IO.puts("Hello, #{name}")
  end
end

比 Haskell 那套 Monad 要直观多了。

而且 模式匹配管道操作符 让我眼前一亮:

代码语言:txt
复制
[1, 2, 3, 4]
|> Enum.map(&(&1 * 2))
|> Enum.filter(&(&1 > 4))

这段代码意思是:

取一个列表 → 每个元素乘以 2 → 过滤掉小于等于 4 的数。

简洁、优雅,一气呵成。

但我依然卡住了。

卡在 不可变性

在 Python 里,我每天都写上百次:

代码语言:txt
复制
x = 10
x = x + 1

可在 Elixir 里,这行会直接报错:

代码语言:txt
复制
x = 10
x = x + 1   # ❌ cannot rebind x

在 Elixir 中,变量一旦绑定,就不能修改。

每次“更新”,都要返回一个新变量。

这完全颠覆了我对“程序运行”的直觉。

于是,在经过几天的思想挣扎之后,我再次选择了放弃。

* * *

三、为什么函数式编程这么难?

后来我慢慢想明白:

函数式编程不是语法上的变化,而是思维方式的转变。

  • 在命令式语言里(Python、Java、Go),我们习惯“改变状态”:
代码语言:txt
复制
> 设置一个变量 → 修改它 → 在循环中继续修改它。
  • 在函数式语言里,代码更像数学函数:
代码语言:txt
复制
> 给输入 → 返回输出,不允许偷偷改变外部世界。

你必须把“变量”看作不可变值,把“流程”看作数据转换的管道

这对大多数程序员来说,简直就是大脑重塑。

* * *

四、放弃两次之后,我学到的三点

虽然我没有坚持用 Haskell 或 Elixir 写项目,但这两次经历让我收获巨大。

1. 纯函数的好处

  • 同样的输入 → 永远得到同样的输出。
  • 没有副作用 → 测试更简单。

2. 不可变性的价值

  • 不会出现“变量被偷偷改掉”的 bug。
  • 代码逻辑更可预测。

3. 你不必 100% 函数式

  • 我现在在 Python 里大量用 mapfilter、列表推导式。
  • 这就是在“偷师”函数式编程,而不必被它绑死。

* * *

五、来自社区的声音:为什么很多人放弃 FP?

在 Reddit 上,关于 Elixir vs Go 的讨论很有意思。

很多程序员提到:

  • Elixir/BEAM 的优势:并发和容错(OTP)、语法优雅、Phoenix/LiveView 体验好。
  • Elixir 的痛点:动态类型对大项目不够友好(有人转向强类型的 Gleam)、CPU 密集型不擅长、部署比 Go 麻烦。
  • Go 的优势:类型安全、性能好、生态健全、编译后单一二进制,部署简单。
  • Go 的不足:并发模型虽强,但不像 OTP 那样“电池全配”。

一句话总结:

Elixir 更像是写“长期在线的高并发系统”,Go 更像是写“工具、基础设施与 CPU 密集任务”。

这也解释了为什么很多人尝试 FP 后会退缩:

它的学习曲线确实陡峭,也并非所有项目都需要它的“数学式优雅”。

* * *

六、落地思路:如何用 FP 的思想而不被劝退?

如果你也想尝试 FP,我给几个小建议:

1)别从 Haskell 开始

它太学术了,入门容易劝退。

可以考虑 Scala(对 Python 程序员更友好),或者 Elixir(语法更直观)。

进一步想要强类型 + BEAM,可以试试 Gleam。

2)混合使用,而不是极端纯粹

在 Python、Java、Go 里用纯函数、不可变思路,就能收获一部分好处:

  • 避免全局变量;
  • 优先返回新值而不是就地修改;
  • 利用 map/filter/reduce 或者流式 API;
  • 将副作用隔离到边界(I/O、网络、数据库);
  • 用小函数拼装复杂行为(组合优于继承)。

3)降低环境负担:用工具把“试错成本”降到最低

很多时候,劝退点不是语言本身,而是“装环境”。

我后来用Servbay这类本地多语言环境管理工具,体验就顺畅许多:

  • 多语言并行:同时开 Python、Go、Elixir / Phoenix 的实验项目做对比;
  • 隔离依赖:各自版本与依赖互不干扰,删除重建也不污染系统;
  • 一键起停:把精力放在范式学习与小实验上,而不是一天到晚修 PATH、装 VM、配编译器。

对于“想尝鲜但又怕折腾环境”的同学,这是非常现实的解法:先在熟悉语言里引入 FP 风格,再把小实验迁到 Elixir/Scala/Gleam,对比体会差异与收益。

* * *

七、从“理念”到“方法”:给想把 FP 用到生产的人

如果你已经能在日常编码中自觉地“少副作用、重不可变、用纯函数”,下一步可以考虑把 FP 落到团队工程实践里:

  • 代码层面
代码语言:txt
复制
-   约定:业务函数默认纯函数,I/O、副作用集中在接口层。
-   结构:小函数 + 组合优先,避免巨石函数;
-   数据:不可变数据结构优先(即便语言不强制,也尽量不原地修改)。
  • 测试与质量
代码语言:txt
复制
-   纯函数单测覆盖率高,Mock 难度低;
-   副作用在边界,端到端测试专注流程正确性。
  • 并发与可用性
代码语言:txt
复制
-   Go 场景:goroutine + channel 的约定式并发,配合 context 超时与 errgroup;
-   Elixir 场景:OTP 的 supervision tree、进程隔离与自愈,天然容错。
  • 部署与运维
代码语言:txt
复制
-   Go:静态编译、单文件交付,容器化与多架构镜像更省心;
-   Elixir:考虑 release、节点编排与可观测性,充分利用 OTP 的能力。
  • 团队心智升级
代码语言:txt
复制
-   通过 code review 强化“无副作用边界”的习惯;
-   为新人准备 FP 风格的代码范例与重构清单;
-   从“小而确定”的模块开始推广(比如纯函数的定价、折扣、风控规则)。

* * *

八、结语:放弃不等于失败

我两次放弃了函数式编程,但我依然感谢它。

因为它让我更清楚地认识到:

  • 写代码不只是“能跑”,还要“能维护”;
  • 思维方式比语法更重要;
  • 即便没成为 FP 程序员,我依然因为 FP 受益匪浅。

别焦虑于“学不会”

哪怕只学到“写纯函数、少用副作用、尊重不可变”,你已经在向更专业的工程师靠拢。

至于要不要上手 Elixir/Haskell/Scala?不妨先在熟悉的语言里用起来,再用 ServBay 搭个本地实验场,循序渐进,择其善者而从之。

* * *

开放问题

  • 你尝试过函数式编程吗?
  • 你觉得它在现实项目里值不值得用?
  • 你更偏爱 Go 还是 Elixir?为什么?

欢迎在评论区分享你的故事与实践。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、第一次邂逅:Haskell 的幻觉与崩塌
  • 二、第二次尝试:Elixir 的希望与崩溃
  • 三、为什么函数式编程这么难?
  • 四、放弃两次之后,我学到的三点
  • 五、来自社区的声音:为什么很多人放弃 FP?
  • 六、落地思路:如何用 FP 的思想而不被劝退?
    • 1)别从 Haskell 开始
    • 2)混合使用,而不是极端纯粹
    • 3)降低环境负担:用工具把“试错成本”降到最低
  • 七、从“理念”到“方法”:给想把 FP 用到生产的人
  • 八、结语:放弃不等于失败
  • 开放问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档