作者closer76 (克楼瑟)
看板Programming
标题Re: [问题] 请问Erlang很难吗?
时间Fri Apr 30 11:48:33 2021
※ 引述《iLeyaSin365 (365)》之铭言:
: 最近看到三个语言都跟平行程式有关
: 分别是:Erlang 、Haskell、golang
: 虽然最晚,但Go语言因为是Google 出的,教学与应用似乎最多
: 而Haskell 较少,但我发现Erlang的教学好像没多少
: 有翻书,感觉跟 其它两个风格更复杂,琐碎...
: 是不是它算平行程式语言里最难的?
: 用途也最狭隘?我还不太清楚什麽是
: 平行程式以及函数式语言的意义。
先说明一下:我个人用 C/C++ 写作业/讨生活已经 20 多年。
这两、三年才因为兴趣开始接触函数式语言(主要是学 Haskell)。
但没有拿函数式语言真的写过什麽中、大型的专案,工作上也没有用到,
对这方面的认识可能没有比一般人多多少。下面算是我这几年的一些小心得吧!
你列的三种语言,Erlang 和 Haskell 都算是纯粹的函数式程式语言(简称 FPL)。
Go 只能说受到 FPL 的影响,加入一些适合 FP-style 写程式的语法,不算是 FPL。
-------------------------------
「函数式程式设计」中的「函数」和「程序式程式语言(例如 C)」中的我们常说的
「函式」其实不太一样。「函数」其实更接近数学中的定义:y = f(x)。
当你输入了参数 x,你就会得到一个结果 y。而且,
不论在何时何地,只要输入的 x 相同,输出的 y 绝对是一样的。
这点非常重要!
以 FPL 的术语来说,这就是「没有副作用 (side-effect)」。
相对来说,C 语言的函式就有可能会因为时间、环境、全域变数、内部状态等因素,
导致在不同的情境之下,同一个函式加上相同的参数,输出结果却不同。
当然你可以举出一万个例子,说明 C 语言的这个功能多麽强大、有用。
但就是因为太强大、太有弹性,导致测试除错变得困难。
另外,如果要作平行处理,也容易发生问题。
(如果有一个函式在不同时间呼叫结果不同,那平行处理这种执行顺序不一定的情况下,
你怎麽能保证执行的结果如你所愿?)
平行处理不一定要用 FPL;
但因为 FPL 有「无副作用」的特性,所以特别适合进行平行处理。
-------------------------------
FPL 另外一个常见的特性(或说是限制),就是「变数」的值不能更改 (immutable)。
也就是说,
int a = 0;
a = 2; // 给予 a 新的值
这样的行为在 FPL 一般来说是做不到的。
(我知道有些 FPL 可以;但可以做到的,通常就被称为 non-pure FPL)
因为这样的限制,在程序式程式语言中常见的「回圈 (iteration)」就没办法用;
必须改用「递回 (recursion)」来做。程式设计者的思维就必须改变。
-------------------------------
在 FPL 中,函数可以当成变数来用。(High-Order function)
你可以把它当成另一个函数的参数,或者是回传值。
这里只有轻描淡写两句,但实际上它有极大的弹性。
你可以轻易地组合数个函数,生成一个功能更强大的新函数。
熟练的人可以用得出神入化,一行程式码搞定复杂的演算法。
但对新手来说可能就要花个五分钟才能搞懂这行程式码在做什麽。 XDD
-------------------------------
另外还有一些特性,可能不是每个 FPL 都有的。
例如 Erlang 有「模组热抽换」的功能。
(你可以想像程式还在执行的时候,可以更新其中某个 DLL,不需要重启。
这是因为 Erlang 主要用在通讯设备上,不能随便断线更新)
或是 Haskell 的 lazy-evaluation 特性等。
这些功能都有它们的擅长之处。
-------------------------------
至於 FPL 好不好学....
我个人认为:不好学,但值得研究。
以我学 Haskell 为例,首先要克服的障碍就是几乎所有的问题都要用递回来解决。
当然 Haskell 提供很多很方便的函数,可以省掉很多麻烦;但要学习、活用这些函数
还是需要时间和经验。
另外,Haskell 是可以自行组合、定义符号的。
所以你可以在程式码中看到很多如 <*>, <+>, >->, +<><.... 等奇怪的符号。
看不懂时又很难 google....
但随着平行运算越来越重要,软体业界对於 FPL(或用非 FPL 进行 FP)也越来越重视。
像是 Google 的搜寻引擎命脉 MapReduce,就是受到 FP 的启发而开发出来的。
也有很多公司认为 FP 易开发(这个我还没嚐到甜头XD)、易维护,
所以也改用 FP 的方式开发软体。
就算,退一万步来说,我的工作还是要大量使用 C 语言,
我也会利用 FP 的思维,降低函式的副作用,减少错误发生的机率。
我想都是有好处的。
-------------------------------
如果你真的想学 FPL,我的建议是不要从 Erlang 下手。
Erlang 比较专精在通讯基础建设的领域,除非工作上会用到,否则不容易学。
而且资源真的不够多。
建议先学其他的 FPL,等工作真的有需要再去学 Erlang。
Haskell 在 pure FPL 中资源算多的,想要学最纯粹的 FPL 可以考虑。
以实用性来说的话,可以玩玩 Scala、F#、Clojure、Elixir 等。
但我没有深入玩过,不敢保证好不好玩。 XDD
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.137.228.39 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Programming/M.1619754515.A.3F8.html
※ 编辑: closer76 (223.137.228.39 台湾), 04/30/2021 12:00:53
1F:推 iLeyaSin365: 谢谢提供心得,聊赠一点p币 111.82.59.67 04/30 12:26
2F:→ iLeyaSin365: 是啊 虽然我没学多久写程式 但也觉 111.82.59.67 04/30 12:26
3F:→ iLeyaSin365: 得编程的思维很重要 所以想接触这 111.82.59.67 04/30 12:26
4F:→ iLeyaSin365: 些 111.82.59.67 04/30 12:26
其实「初学者是否应该学 FP」也是我在思考的问题。
国内的大学几乎都是以实用导向,由程序式、物件导向式入门。
当年我念书时,FP 会开在大三的选修课,但也不是很热门。
国外以前在 CS101 会教 Lisp(古老的 FPL);但近年也改成教 Python...
5F:推 pinefruit: 感谢分享~180.218.168.129 04/30 15:57
6F:推 tylpk: 推这篇,之前也想学Erlang,但有了Go之後,223.136.120.204 04/30 16:42
7F:→ tylpk: 需要的东东都有了,就提不起劲了。FPL最难223.136.120.204 04/30 16:42
8F:→ tylpk: 的就是模式匹配的写法,平常都不会想这样写223.136.120.204 04/30 16:42
9F:→ tylpk: 。223.136.120.204 04/30 16:42
程式语言是工具,符合需求就好。我最近也少碰 Haskell 了,玩 Rust 比较多。
不过 pattern matching 是好东西啊! XDD
尤其是在没有 NULL、改用 Option 概念的语言(例如 Haskell 和 Rust),
用了 pattern matching 程式码会变得乾净许多。 :)
※ 编辑: closer76 (223.137.228.39 台湾), 04/30/2021 18:27:10
10F:推 tylpk: rust我最喜欢的就是可以用_来做Hex数字的 223.136.89.3 05/03 05:25
11F:→ tylpk: 分隔点,除错设定值时非常好用。 223.136.89.3 05/03 05:25
13F:→ tylpk: /blob/master/src/main.rs 223.136.89.3 05/03 05:27
14F:推 dododavid006: 推 rust ,这语言的概念我觉得很适 36.233.125.241 05/03 11:22
15F:→ dododavid006: 合有用过其它语言的人去了解试试 36.233.125.241 05/03 11:23
16F:推 preed: 好文章 61.70.82.73 06/14 09:58
17F:推 MoonCode:125.228.246.251 11/05 14:47