导言
关于本书
这是本教程的第一句话!读到这里也许是你第一次踏入Erlang的殿堂,让我们先坐下来聊聊。
这一切都起源于一部非凡的杰作——Miran Lipovaca的Learn you a Haskell for great Good!(LYAH),它将Haskell语言描述地迷人若星,亲切似风,宛立如邻家一袭白衣的少女。令我立即萌生了来一份这样的erlang教程使命感。由于我与作者相识,便询问于他,后者毫不客气地赞了我,对erlang似乎也颇有兴趣。
所以我寄希望于本书能为那些对命令式编程有一定基础,对函数式编程了解或不了解的人打开一扇通往erlang的门,同时我希望它做一本诚实的书,忠实地展现erlang是什么,具有怎样的优劣势。
什么是Erlang
首先,erlang是一门函数式编程语言。如果你曾与命令式编程语言共舞,那么对i++这类语句一定已经习以为常,然而这在函数式编程中是不被允许的。事实上,连改变变量的值都是明令禁止的!乍一听这好像很奇怪,但想想你的数学课,其实这才是你曾经学过的:
y = 2
x = y + 3
∴x = 5
继续添加以下内容:
x = 5 + 1
x = x
∴ 5 = 6
这将让你的数学老师狗带!函数式语言认为:如果我声明x是5,那么从逻辑上我不能声明它又是6!因为这不属实,这也是为什么对于同样的参数,函数应该总返回相同的结果:
x = add_two_to(3) = 5
∴x = 5
对于相同的参数,函数总返回相同的结果叫做引用透明性。正是这项特性让我们可以用5来替换函数add_two_to(3),因为3+2的结果永远是5。这意味着我们可以将一打函数合成一个来解决一个复杂的问题而不必担心出错。符合逻辑而又整洁,不是么?不过(引用透明性)有个问题:
x = today() = 2009/10/22
--wait a day
x = today() = 2009/10/23
x = x
∴ 2009/10/22 = 2009/10/23
不!我美妙的等式!他们突然全错了!我的函数怎么会每天返回一个不同的结果?
但显然,这些情况下不保证引用透明性会更好使。所以erlang拥有一个对函数式编程非常实用的思路:遵循函数式编程的最纯粹原则(引用透明性,变量不可变等),但在面临实际问题时抛弃掉这些原则。
通过以上内容,我们已将erlang定义为一门函数式语言,但接着要对erlang的并发和高稳定性来一个大大的强调。为了同时运行大量任务,erlang使用了角色模式(actor model),其中每个角色都是虚拟机中的一个独立进程。形象点说,如果你是Erlang世界中的一个角色,你将孤独地坐在一个黑暗无窗的房间里,等待着有新邮件到达你的信箱。
Erlang的角色模式可以想象成一个所有人都独自坐在自己的房中,完成一些独特的任务的世界。他们之间只写信交流,仅此而已。听起来有些生无可恋(虽然邮政服务将迎来新的纪元),但这意味这你可以叫许多人为你做不同的事,而不必担心有人暴走跑出来屠杀其他人,因为除你之外,他们甚至不知道其他人存在(这很棒!)
从比喻中脱离出来,Erlang要求你写的角色(进程)们除了消息外不能共享任何代码。(角色间)每次交流都是明确、可追踪和安全的。
虚拟机和函数库还支持运行时更新代码而不必中断程序、轻松地在多台电脑上部署你的代码、以及简单而又强大的错误处理方式。
Erlang的错误恢复、代码组织、角色模式、分布式和并发都听起来很赞,所以接下来:出来吧!下一节。
别喝太多鸡汤
(Don’t drink too much Kool-Aid)
本书中还会有许多像这样的橙黄色章节。在狂热者的宣传下,Erlang现在变得流行起来,并使人们对他的预期远远超过了实际。如果你是一名过于“热情“的学习者,这些提示将在合适的时候提醒你脚踏实地。
第一件事是关于Erlang轻量级进程带来的高并发能力。Erlang的进程确实十分轻量:你可以同时拥有几十万个进程,但这并不意味着你需要这么做,如果理由只是你能这样而已。比如,制作一个射击游戏,将所有事情包括子弹都交给一个独立的角色处理简直是疯了。估计在那样的游戏中你唯一能射到的就是自己的脚。角色之间相互传递消息仍然是有一定消耗的,如果你将任务划分过细,程序将变得更慢!
当我们探索到真正需要考虑这个问题时,我将会深入展开这部分,现在,只需记住随机将问题并行处理并不足以让程序更快即可。别伤心,会有几百个进程大展身手的时候!只是不是所有时候都是这样罢了。
erlang也被说成战斗力跟计算机处理器数量成正比,但大部分情况下事实并非如此:虽然这是有可能的,但大部分问题并不具备同时执行所有任务的行为特质。
除此之外,我们脑海中还得有一个概念:也许erlang非常擅长做某些事情,但技术上其他语言也可以达到同样的效果,反之亦然。评估每个任务的需求,然后根据问题的解决方式选择对的工具。Erlang并非圣枪银弹而且实际上在处理图像、信号、操作系统、设备驱动等问题上非常垃圾。而一旦到了诸如大型服务器软件(例如:queues,map-reduce), 嵌入其他语言来做一些提升,高层协议实现等领域时,erlnag将闪闪发光。某些中间领域就由你自主决定了。而且你也不必将自己和erlang陷入服务器软件的围城,已经有人正在进行令人意外而又惊喜的事情。UNICT的一个队伍创造了机器人IANO使用Erlang语言编写AI,并赢得了2009年eurobot竞赛的银牌。另一个例子是Wings 3D,Wings 3D是一个开源的3D模型编辑器(并非渲染器),它由erlang编写并因此获得了跨平台的能力。
(下面两段懒得翻译了)
你需要的潜水装备…
开始Erlang之旅只需一个文本编辑器和Erlang环境。你可以从Erlang官方网站获取源代码(source code)和Windows二进制文件(Windows binaries)。我不会过多讲解安装细节,对于Windows用户,直接下载并运行二进制文件。别忘了将Erlang安装目录添加到系统Path变量中,使得命令行可以访问到该目录。
在Debian-based Linux distributions上,你可以使用 $apt-get install erlang来安装Erlang。在Fedora(如果你已经安装了’yum’),你可以使用# yum install erlang来达到同样效果。然而,这些仓库通常存放的不是最新版的安装包。使用旧版本可能会导致你在某些应用得到一些和本教程不一样的表现。所以我建议你从源代码进行编译。查询源代码包中的README文件,并通过Google获得你需要的安装细节,它们一向在这方面做得比我好。
在FreeBSD,你可以有很多选择。如果你使用portmaster,你可以使用portmaster lang/erlang.对于标准端口,你可以使用cd /usr/ports/lang/erlang;make install clean。或者,你想使用安装包,运行pkg_add -rv erlang。
如果你在OSX系统上,你可以使用
brewinstallerlang(使用Homebrew),或者
port install erlang(如果你更喜欢MacPorts)。
可选的:Erlang Solutions Ltd。支持大部分主流平台,通常非常有用(选择’Standard’ 发布)。
备注:本书写作时,使用的是Erlang R13B+ 版本,为了更好的结果,你应该使用一个更新的版本。
何处求助
你可以从几个地方获得帮助。对于linux用户,可以访问man page上不错的技术文档。Erlang有一个lists(我们很快就会见到)模块来以列表方式获取文档,输入$ erl -man -lists就行。
在Windows上,安装包已经包含了HTML文档。你可以在任何时候从官方网站下载,或者访问安全的替代网站。
当你需要一些整洁的代码时,可以到这里阅读一些好的代码规范。本书的代码也将遵循这些规则。
有时,仅仅获取技术细节是不够的,在这种情况下,我主要习惯访问两个地方:官方邮件列表(你应该遵循它以学习到很多东西)以及irc.freenode.net的Erlang区。
噢,如果你是一个在寻找食谱的人(if you’re the type of person to go for cookbooks and pre-made recipes), trapexit就是你要找的地方。他们以论坛和wiki的方式镜像了邮件列表,通常都十分有帮助。