【数据类型篇】
数字(integer + float)和原子(atom)是最基础的常量,说它们最基础,是因为它们没有结构。数字可以计算,原子不可以计算(只能进行比较)。Erlang支持任意长整数的计算,浮点数的计算精确到小数点后16位数,你可以理解为1/(10^16)就是所谓的“1”,在此基础上的任意“长整数”的计算。
元组(tuple)和列表(list)是建立在数字和原子的基础上,有一定结构的常量,你说是数字和原子的结构也对。tuple把固定数目的item聚集在一起,类似C中的array或struct,而list把不定数目的item聚集在一起,类似C中的stack,我们很容易在开头添加或删除item,而保持list类型不变。正因为如此,我们可以用tuple模仿list,从某种程度说,list不过是tuple细分出来的一个常用的结构形式罢了,但在实现上性能可能进行了优化。tuple可以嵌套,类似C中的tree,list也可以嵌套,但是现实意义不是很大。
记录(record)之于元组(tuple),就好比字符串(string)之于列表(list)。记录是元组的变种,本质上还是元组,字符串是列表的变种,本质上还是列表,它们都是为了更好的可读性而产生的。record在tuple的基础上,对每个item进行命名(关键字与值一一对应),而无需频繁地在tuple中插入原子增加可读性,这样可以节省大量的成本;string在list的基础上,限制每个item只能是printable character对应的整数,不论是输入字符串还是输出字符串,都变得更加人性化了。至于string为什么不是tuple而是list,可能是因为字符串处理,list相对于tuple来说更加灵活。
在Erlang中,“变量”并不是通常所说的变量,它一旦赋值就不能修改,就好比取名字一样,我们管这个人叫“张三”,就不能等下又管另一个人叫“张三”,这样我们沟通起来就不会产生误会,同样,在Erlang中,进程之间为了沟通起来不会产生误会,一旦“变量”指代了某个常量,它就不能指代为其他常量。所以Erlang的“变量”叫做名字更加贴切,而所谓的“赋值”与其说是一次性赋值,不如说是绑定,而绑定后调用=操作就叫匹配,叫好比有个新的名字,刚开始大家都没有用它来指代某个人,第一次使用=操作后,这个新的名字与某个人发生了绑定,往后再使用=操作,就都是匹配了。同样,与其说=是赋值号,不如说它是绑定号或匹配号。
模块(module)类似Java的package,把多个函数打包在一起,在erl中不能像在module文件中那样直接定义函数,只能创建匿名函数(anonymous function)。
> fun(X) -> X * X end (9).
你也可以绑定该匿名函数到某个变量重复使用。
> Square = fun(X) -> X * X end.
> Square(9).
说到函数的绑定,如果需要绑定某个module的函数到某个变量中,需要用到函数引用(function reference):fun Mod:Func/Arity(如果引用当前module的函数,Mod可以不写),在Erlang中,同一个module的两个函数即使名字相同,只要参数的个数不同,就是两个不同的函数。
> Max = fun erlang:max/2.
> max(2, 3).
匿名函数和函数引用,在某种程度上,是同一个概念来的,因为它们都可以作为其他函数的参数,这样就产生了高阶函数,而Erlang之所以叫做函数编程语言(functional programming language),也正是因为函数的参数还可以是函数。
guard不知道怎么翻译,它是一个关系表达式或BIF(erlang模块的函数),对于模式匹配(pattern matching)来说,显然它是一个很好的补充。对于函数来说,真正的匹配,不单单是一个模式上的匹配,还需要满足其他的条件,而这恰好就是guard的强项,就好象多个保卫(guard sequence)一样,共同保护守卫着模式匹配。在逻辑学上,guard就是一个谓词,guard sequence就是一个没有量词的析取范式,";"就是∨,","就是∧,结果就是true或false。
说到模式匹配和guard,就不得不提到case表达式和if表达式,当函数的部分参数需要进行模式匹配和guard,而其他部分与之无关时,如果使用外部的模式匹配和guard的话,会搞得相当复杂(如clause数增多,逻辑不清晰,出现重复代码,性能下降等),这时候就可以在内部使用case表达式对这部分参数进行模式匹配和guard,同样,当guard也会引起类似的复杂度时,我们也可以在内部使用if表达式进行描述。可以说,case表达式是模式匹配+guard的一种辅助,而if表达式则是guard的一种辅助,你说if表达式是case表达式的简化版也没错,因为case表达式确实也包含了guard的功能。
binary(二进制)这个类型,顾名思义,就是为了能够把数据粒度细到一个binary(bit)而产生的。我们知道,大的integer为bignum类型,tuple和list有一定结构,空间利用率都不是很高,当存储或传输它们时,就会增加不必要的成本,我们可以通过某个协议(the Erlang external term format)压缩成一串字符(raw data),而压缩后的类型就是binary了,当存储或传输完后,我们可以再通过这个协议解压还原出最初的数据。Erlang的任何数据类型,通过term_to_binary/1和binary_to_term/1两个函数,都可以与binary进行互换。binary没有嵌套,即没有结构,只是一块扁平化的连续内存空间,它的每个item只能是0~255的整数或字符串,因为0~255的整数和字符都可以用一个字节表示,使得binary的数据粒度细到一个byte(8个bit),而真正让binary的数据粒度细到一个bit的是the bit syntax,它使得每个item的大小不必是8个bit的倍数,而可以是任意的bit数,只要所有item的bit数加起来是8个bit的倍数即可。
进程词典(process dictionary)是一个小型的key-value数据库,每个进程(process)都有一个。由于我们可以修改每个key对应的value,可能会产生side effect,所以不到万不得已,尽量不要使用,当然啦,如果只是用来存储write-once variable,那是非常合适的。
reference意思为编号或标记,Erlang能够保证make_ref/0产生的任意两个reference都不相同,也就是说,reference是用来产生唯一的标识符的,主要在远程过程调用(rpc)中用来标识消息(message)。
【并发进程篇】
待续。。。
Erlang的设计理念确实很强
对“Erlang的设计理念确实很强”的回应
《Erlang 程序设计》热门书评
-
一本不错的入门书
19有用 2无用 Arbow 2007-07-17
《Programming Erlang》Joe的新书,买了个电子版,在花了一些时间读了一下之后,发发牢骚,写写读后感。书不太厚,也不薄,500多页,但是单纯附录就占了100+,Appendix F Module and Function Reference,有凑页面的嫌疑。有仁兄打印了整本书,叠起来...
-
很实在的书
9有用 0无用 维修各类UFO 2009-07-15
老头在书里明白的表示了对现在的erlang实现并不非常熟悉,尤其是一些偏门的细节,毕竟erlang的开发已经交由一个专门的小组做,老头可能专心研究容错和并行的理论去了,或者又有啥新的东西要设计。这样带来的好处是老头不像很多语言的创始人那样揪着自己得意却实际没人用的特性大段吹牛,这本书很是实在,讲的点...
-
Erlang程序设计中文版(书评和笔记)
5有用 0无用 Steven 2013-09-14
在最近的一个多月时间里,我利用业余时间学习了Erlang,这是一门面向并发模式编程的语言,她采用函数式的一些思想,加上强有力的库,在20多年的锤炼中,已经算是世界顶级的并发编程语言之一,当然有些不足的是多少年都不变的语法特性使得这门语言的特性比较死板。先吐槽一下: ...
-
最全面实在的erlang学习书
5有用 0无用 eric.33.yu 2010-04-06
Joe老头作为erlang之父写了这个书, 从erlang的设计理念, 到Erlang的语法,开发环境,OTP,到系统的诊断, profile,娓娓道来,顺着他的节奏, 读者会很容易进入这一神奇语言的大门!强烈推荐!http://blog.yufeng.info...
-
更有趣的不是这本
3有用 1无用 wangii 2008-02-02
而是Joe Amstrong的PhD thesis.Declarative和Procedure已经争论了几十年了,现在看来,在multi-core时代Declarative programming有重新崛起的迹象。比较吸引我的地方是这种思路下很多让Procedure Programming很难解决的...
书名: Erlang 程序设计
作者: ARMSTRONG
出版社: 人民邮电出版社
原作名: Programming Erlang: Software for a Concurrent World
译者: 赵东炜 | 金尹
出版年: 2008
页数: 427
定价: 79.00元
装帧: 16开
ISBN: 9787115188694
