Erlang的Hello World:一个计数程序
acm queue 9月的杂志的主题是The Concurrency Problem,力推了Erlang这个语言,其中有篇文章简单的介绍了下这个message-oriented语言。
查了下这个名字的读法,正确的读法应该是air-lang,这里元音a的发音和bang中的a一样。
文章中的第一个程序就有点令人费解,主要原因在于Erlang的语法和一般的imperative language差别很大,和functional language比较类似,但是本质上也有很大的不同。
以Java的一个计数程序为例
// A shared counter.
public class Sequence {
private int nextVal = 0;
// Retrieve counter and increment.
public synchronized int getNext() {
return nextVal++;
}
// Re-initialize counter to zero.
public synchronized void reset() {
nextVal = 0;
}
}
这个程序的功能不用多说了,一个同步的计数程序。它的Erlang翻译版的代码为
-module(sequence1).
-export([make_sequence/0, get_next/1, reset/1]).
% Create a new shared counter.
make_sequence() ->
spawn(fun() -> sequence_loop(0) end).
sequence_loop(N) ->
receive
{From, get_next} ->
From ! {self(), N},
sequence_loop(N + 1);
reset ->
sequence_loop(0)
end.
% Retrieve counter and increment.
get_next(Sequence) ->
Sequence ! {self(), get_next},
receive
{Sequence, N} -> N
end.
% Re-initialize counter to zero.
reset(Sequence) ->
Sequence ! reset.
初看这个程序自然是一头雾水,不过程序的函数式风格味还是很浓的。
前面提到,Erlang是基于message的,或者说message sending机制是包含在语言系统内部的,语法就是 pid ! message
接下来再来分析这个简单的程序。开头两行是模块和函数声明,略去。make_sequence开始这个进程,spawn/1内置函数创建一个新的进程,并返回pid到调用者。
初始时运行的函数是sequence_loop(0),这个函数接收两种信息,用receive表达式声明:如果收到形式是{From, get_next}的信息,就返回当前的N并调用sequence_loop(N+1),这样下一次收到同样的信息时就能返回N+1了;reset则等价于Java版本中的n=0语句。
get_next/1则是发送给pid为Sequence的进程 {self(), get_next} 这样一个信息,上面解释的sequence_loop/1函数收到这个信息后会返回一个 {self(), N} 的tuple给get_next/1,收到这个信息后get_next/1就能返回N这个值了。
最后reset/1函数则是发送给Sequence一个reset信息。
这个简单的程序里能大致窥见一些Erlang的特点,尤其是它基于信息发送的本质。