你们认为函数式编程语言未来可期吗?

2020-01-09 13:22:12 +08:00
 FaiChou

这几天有三个关于语言类讨论的帖子:

看了讨论内容或多或少都有些提到了 FP 的概念, 貌似 FP 概念在大众已经流行起来了?

结合今年我们老板发的一篇为什么函数式编程没有流行?, 以及今年我们公司全员学习和使用 Clojure, 博客最后有一段:

未来是 FP 的,现在已经是大概率事件。

OO -> 混合 -> FP

FP 这个词注定会被用烂,这是另外一个故事了。

想听一下大家对 FP 语言的看法, 未来发展如何, 以及你们平时使用过的 FP 语言有哪些? 对比 OO 有哪些优势劣势? 你们有在业务项目中使用 FP 语言吗?

(这不是一个关于某种语言讨论的帖子, 不想引起战争)

8533 次点击
所在节点    程序员
47 条回复
cmdOptionKana
2020-01-09 13:39:20 +08:00
1. 纯 FP 没有未来。

2. FP 的其中一些优点会被发扬光大。

3. 纯 FP 太考验智商了…… 而智商就是成本,不管谁投资搞项目都希望降低成本,因此如果招聘普通智商的程序员就能完成任务,老板就不可能花更高价钱去招聘特别高智商的程序员。
ma836323493
2020-01-09 13:42:17 +08:00
数据和函数分离,容易造成函数重复,
abcbuzhiming
2020-01-09 13:44:56 +08:00
我不认为 FP 真的流行了,别的不说,FP 的核心概念,“变量不可变”的特性有几个人真的用了?所谓 FP 流行不过是函数像参数传来传去这一点被 js 带起来了而已。

未来不是 fp 的,如果未来是 fp,那么 erlang 这种纯函数语言早就该流行了。所以未来肯定还是混合的
rogwan
2020-01-09 13:47:42 +08:00
项目终归还是要人来维护的,一方面是团队规模,一方面是项目生命周期,这两个方向一扩展,很多人很多年的项目,用 fp 不敢想象
FaiChou
2020-01-09 13:51:04 +08:00
@cmdOptionKana #1 3 是支持观点 1 的吗? 可以解释为什么 FP 考验智商吗?

我可以先讲个例子: 在 js 中处理复杂数据一般用 Immutable.js 或者用 map/reduce/filter/concat 等常见的 no-side-effects 函数, 而这刚好是 FP 的本职, 比如 clojure 的所有函数, 完全可以处理任何复杂数据, 不限于 js 这几种高阶函数, 并且如果觉得写的 FP 代码难以理解, 可以搭配使用 https://github.com/redplanetlabs/specter 等工具.

所以我认为 学习 100 种 FP 的方法处理问题, 比使用几种方法组合来处理问题要简单直白的多.
westoy
2020-01-09 13:51:47 +08:00
07~08 年那会儿最火吧

然后就熄火了........
FaiChou
2020-01-09 13:52:10 +08:00
@cmdOptionKana #1
@FaiChou #5
抱歉讲的例子有点不对, 例子是 OO 语言的高阶函数来对比 FP..
luozic
2020-01-09 13:54:08 +08:00
缺点:
1.纯函数式难以利用之前几十年大部分积累的面向对象的软件工程实践。
2. 纯函数式比较适合数据处理,不适合复杂业务建模。
优点:
1.合理规划之后的纯函数式可以无缝由 iaas----paas---saas- serverless
2.并发比较容易实现。
人员 ide 缺点:
1.fp 的算法和面向对象的根本不一样,有大量的转换培养成本。
2.fp 的基础设施问题,现在支持 fp 的基础设施少得不行,基本都得借助 MQ 来解耦传统设施对于函数式架构的污染。
3.fp 的优化,debug 等等,友好的 ide 比较少。
akehgnaix
2020-01-09 14:00:17 +08:00
@luozic 说出了我的心声。FP 对数据处理有好处,但是面对业务的过程式逻辑时还需要翻译为函数式表达,不仅仅考验智商,兼职浪费时间。
FP 强调的不可变导致的内存资源浪费也是非常可怕的
wangyzj
2020-01-09 14:03:18 +08:00
fp 除了看着语法优雅之外还有啥优点?
FaiChou
2020-01-09 14:14:20 +08:00
@wangyzj #10 语法优雅不见得. 我觉得优雅的是 Objective-C: [PageAViewController doSomethingBy: modelB], 哈哈哈, 开个玩笑, 但好像真没见过几个说 fp 语法优雅的, 一大堆括号(lisp 系列)有啥优雅的?


@akehgnaix #9 业务的过程式逻辑翻译为函数式表达? 这里我觉得翻译为对象更考验能力. fp 只关心数据结构如何, 以及用什么工具处理数据, 从数据库 /redis/内存中的数据到用户客户端的展示, 不是将数据变成界面吗? 难道有比 fp 更适合处理数据的吗? 最终调用客户端的 api 来展示数据完事, 中间的数据处理交给函数. 另外 fp 内存浪费之说, 更不敢苟同, 比如 fp 可能会经常写递归, clojure 没有尾递归优化, 但提供 recur 和 lazy-seq 来处理. 所以内存浪费可能是程序员但事, 和编程语言无关.
xuanbg
2020-01-09 14:32:48 +08:00
函数式的语法对比非函数式的语法如 Java 有什么优势吗?这个问题的答案是:相对好处而言,劣势更加明显。所以,函数式编程不存在流行的基础。你可以学习,但不必非函数式不可。
zhuangzhuang1988
2020-01-09 15:22:18 +08:00
// Inspired by http://www.cs.utexas.edu/~wcook/Drafts/2006/MemoMixins.pdf

// State Monad combined with Continuation Monad (StateT Monad transformer)
type StateContMonad<'s, 'a, 'r> = StateContMonad of ('s -> ('s -> 'a -> 'r) -> 'r)

// Computation Builder
type StateContBuilder() =
member self.Return value =
StateContMonad (fun state k -> k state value)
member self.Bind(StateContMonad contStateMonad, f) =
StateContMonad (fun state k ->
contStateMonad state (fun state' value ->
let (StateContMonad contMonad') = f value
contMonad' state' k))
member self.Delay( f : unit -> StateContMonad<'s, 'a, 'r> ) =
StateContMonad (fun state k ->
let (StateContMonad contStateMonad) = f ()
contStateMonad state k)

let memo = new StateContBuilder()

// Tell me Y
let rec Y f v = f (Y f) v

// Map functions
let check (value : 'a) : StateContMonad<Map<'a, 'r>, option<'r>, 'r> =
StateContMonad (fun map k -> k map (Map.tryFind value map))

let store (argument : 'a, result : 'r) : StateContMonad<Map<'a, 'r>, unit, 'r> =
StateContMonad (fun map k -> k (Map.add argument result map) ())

// Memoization Mixin
let memoize f argument =
memo {
let! checkResult = check argument
match checkResult with
| Some result -> return result
| None ->
let! result = f argument
do! store (argument, result)
return result
}


let execute f n =
let (StateContMonad contStateMonad) = Y (memoize << f) n
contStateMonad Map.empty (fun _ value -> value)

// Example
let big (value : int) = new System.Numerics.BigInteger(value)

let fib f n =
if n = big 0 then memo { return big 0 }
elif n = big 1 then memo { return big 1 }
else
memo {
let! nMinus1Fib = f (n - big 1)
let! nMinus2Fib = f (n - big 2)
return nMinus1Fib + nMinus2Fib
}

execute fib (big 100000)

弟兄们 来学习吧
FireFoxAhri
2020-01-09 16:13:37 +08:00
Scala 路过…
0x11901
2020-01-09 16:15:43 +08:00
讲道理我 3 年前就觉得该学 FP 了,然后想了想直接梭哈上 Haskell 吧!!!




好的,我现在还没有入门……
cyspy
2020-01-09 16:20:00 +08:00
面向数据的映射而非面向步骤,这一点对代码可读性提升巨大
FaiChou
2020-01-09 16:38:49 +08:00
@0x11901 #15 可能你缺一个逼你用 FP 语言的老板
FaiChou
2020-01-09 16:42:29 +08:00
@zhuangzhuang1988 #13 你这个例子很好证明 FP 「考验智商」这一点, 可能很多新手都会被这些概念吓住吧
XIVN1987
2020-01-09 16:50:44 +08:00
RISC vs CISC
微内核 vs 宏内核
FP vs OO

最终流行的肯定不是纯 FP 或纯 OO 编程语言,,而是混合编程语言
dongeast52123
2020-01-09 16:52:51 +08:00
不知道该说什么。
正如我所使用的主要语言—JAVA,从我刚接触的时候(十年前)就有人说 JAVA 已死,结果十年后依旧是企业级应用的老大。而且短时间内其他语言没有任何赶超的期望。
现在的情况是喜欢函数式编程的在说面向对象陈旧,迟早要完蛋。
我总结这些年的各种推测就是。所有的推测都是扯淡,毫无意义,面向对象和 JAVA 至少能活到下一个十年。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/636465

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX