[1] Erlang 語言設計的目標是並發,支持並發的核心機制是進程 "Making reliable distributed systems in the presence of sodware errors" [PDF]
[2] 並發是一種不按照順序執行的能力,並行是從處理執行的角度"是否可以同時做";還有一種角度:並發是邏輯上的同時發生(simultaneous),並行是物理上的同時發生.
[3]其實無論是面向過程還是面向對象,各種編程范式都是對現實世界中的一種抽象 ,只不過關注的點不同
[4]Shared memory could reasonably be called the GOTO of our time: it’s the current mainstream technique for process communication; it has been so for a long, long time; and just like programming with GOTO, there are numerous ways to shoot yourself in the foot.
[5] In Erlang, the message passing primitives are asynchronous, because it’s easy to implement the synchronous form when necessary by making the receiver always send an explicit reply that the sender can wait for.
para(Text) ->
["<p class=\"normal\">", Text, "</p>"].
[11] hipe_bifs:bitarray 提供了類似Redis命令中setbit getbit的作用 @yufeng的介紹
Eshell V5.9 (abort with ^G) 1> hipe_bifs:bitarray(10,false). <<0,0>> 2> hipe_bifs:bitarray_update(v(1), 3, true). <<8,0>> 3> hipe_bifs:bitarray_update(v(2), 7, true). <<136,0>> 4> hipe_bifs:bitarray_update(v(3), 1, true). <<138,0>> 5> hipe_bifs:bitarray_sub(v(4), 1). true 6> hipe_bifs:bitarray_sub(v(4), 2). false 7> hipe_bifs:bitarray_sub(v(4), 3). true 8> hipe_bifs:bitarray_sub(v(4), 4). false 9> hipe_bifs:bitarray_sub(v(4), 7). true 10>
[12] The external term format is mainly used in the distribution mechanism of Erlang.
http://www.erlang.org/doc/apps/erts/erl_ext_dist.html 看下面的測試代碼
Eshell V5.9 (abort with ^G) (node_b@192.168.10.160)1> net_adm:ping('node_a@192.168.10.160'). pong (node_b@192.168.10.160)2> {a_shell,'node_a@192.168.10.160'}!hello_world. hello_world (node_b@192.168.10.160)3> {a_shell,'node_a@192.168.10.160'}!self(). <0.38.0> (node_b@192.168.10.160)4>
Eshell V5.9 (abort with ^G) (node_a@192.168.10.160)1> register(a_shell,self()). true (node_a@192.168.10.160)2> flush(). Shell got hello_world ok (node_a@192.168.10.160)3> flush(). Shell got <5911.38.0> ok (node_a@192.168.10.160)4> node(pid(5911,38,0)). 'node_b@192.168.10.160' (node_a@192.168.10.160)5>
[13] 為什么shell進程重啟了,原來的變量還在
可以看一下 erl5.9.1\lib\stdlib-1.18.1\src\shell.erl的代碼 ,shell進程遇到異常之后的處理邏輯 包含變量綁定的重建shell_rep(Ev, Bs0, RT, Ds0) 方法
Eshell V5.9.1 (abort with ^G) 1> self(). <0.30.0> 2> B=23. 23 3> 1/0. ** exception error: bad argument in an arithmetic expression in operator '/'/2 called as 1 / 0 4> self(). <0.34.0> 5> B. 23 6> b(). B = 23 ok
代碼片段:

shell_rep(Ev, Bs0, RT, Ds0) -> receive {shell_rep,Ev,{value,V,Bs,Ds}} -> {V,Ev,Bs,Ds}; {shell_rep,Ev,{command_error,{Line,M,Error}}} -> fwrite_severity(benign, <<"~w: ~s">>, [Line, M:format_error(Error)]), {{'EXIT',Error},Ev,Bs0,Ds0}; {shell_req,Ev,get_cmd} -> Ev ! {shell_rep,self(),get()}, shell_rep(Ev, Bs0, RT, Ds0); {shell_req,Ev,exit} -> Ev ! {shell_rep,self(),exit}, exit(normal); {shell_req,Ev,{update_dict,Ds}} -> % Update dictionary Ev ! {shell_rep,self(),ok}, shell_rep(Ev, Bs0, RT, Ds); {ev_exit,{Ev,Class,Reason0}} -> % It has exited unnaturally receive {'EXIT',Ev,normal} -> ok end, report_exception(Class, Reason0, RT), Reason = nocatch(Class, Reason0), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {ev_caught,{Ev,Class,Reason0}} -> % catch_exception is in effect report_exception(Class, benign, Reason0, RT), Reason = nocatch(Class, Reason0), {{'EXIT',Reason},Ev,Bs0,Ds0}; {'EXIT',_Id,interrupt} -> % Someone interrupted us exit(Ev, kill), shell_rep(Ev, Bs0, RT, Ds0); {'EXIT',Ev,{Reason,Stacktrace}} -> report_exception(exit, {Reason,Stacktrace}, RT), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {'EXIT',Ev,Reason} -> report_exception(exit, {Reason,[]}, RT), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {'EXIT',_Id,R} -> exit(Ev, R), exit(R); _Other -> % Ignore everything else shell_rep(Ev, Bs0, RT, Ds0) end.
[14] %模塊已經加載而且具有指定的方法導出, 注意最后一個參數是Arity 代表幾目運算
erlang:function_exported(Module, Function, Arity) -> bool()
Types:
Module = Function = atom()
Arity = int()
Returns true if the module Module is loaded and contains an exported function Function/Arity; otherwise
false.
Returns false for any BIF (functions implemented in C rather than in Erlang).
15.
IP地址轉換 1> inet_parse:address("127.0.0.1"). {ok,{127,0,0,1}} 2> inet_parse:address("::1"). {ok,{0,0,0,0,0,0,0,1}} 3> inet_parse:address("300.400.500.600"). {error,einval} And here is Erlang tuple to string conversion: 1> inet_parse:ntoa({127,0,0,1}). "127.0.0.1" 2> inet_parse:ntoa({0,0,0,0,0,0,0,1}). "::1"