Erlang2008 아꿈사Annual Summary현수명soomong80@gmail.comhttp://soomong.tistory.com
30분 동안 Erlang에서 가장 중요한것들만 효과적으로 전달하자.Erlang언어를 처음 접하는 사람들에게 새로운 언어의 장점을 소개함으로써 사고의 폭을 넓힐 수 있다면 성공.
Erlang?병행성멀티코어분산무정지
Erlang ?Ericsson 에서 초기개발되어 사용함수형 언어 가운데 산업에서 쓰이는 유일한 언어자체 Erlang shell 지원Everything is a process.운영체제의 프로세스가 아니라 얼랭 언어 자체의 프로세스.
$ erl1> 1+2.32> A = 5.53> X = hello.hello4> X.hello
애텀불변의 값.1> hello.hello2> rectangle.rectangle
fun익명함수F = fun(X) -> (2 * X) end.인자 X 가 들어왔을때 2*X 를 수행해서 결과를 돌려주는 함수결과값을 F 에 넣는것이 아니라함수자체를 F 에 bound 하는것을의미
$ erl1> F = fun(X) -> (2 * X) end.#Fun<erl_eval.6.5634564>2> F(10).203> Double = F.#Fun<erl_eval.6.5634564>4> Double(5).105> F(5).10
튜플정해진 수의 항목을 하나의 개체로 그룹핑C 의 구조체와 비슷. 익명 구조체1> Rect = {rect, 10, 45}.{rect, 10, 45}2> {rect, X, Y} = Rect.{rect, 10, 45}3> X.104> Y.45{rect, 10, 45}{rect,  X , Y }
리스트[ Head | Tail ]1> L = [1,2,3,4].[1,2,3,4]2> [H|T] = L.[1,2,3,4]3> H.14> T.[2,3,4]5> [H1|T1] = T.[2,3,4]6> H1.27> T1.[3,4,][1 , 2,3,4][H|   T  ][2 , 3,4][H1| T1 ]
Factorialfact.erl-module(fact).-export([fac/1]).fac(0) -> 1;fac(N) -> N * fac(N-1).
Quicksortquicksort.erl-module(quicksort). -export([quicksort/1]).quicksort([]) -> []; quicksort([Pivot|Rest]) ->quicksort([Front || Front <- Rest, Front < Pivot])     ++ [Pivot] ++ quicksort([Back || Back <- Rest, Back >= Pivot]).짧은 코드!
Erlang?병행성멀티코어분산무정지
The Free Lunch Is OverThe Free Lunch?The Free Performance Lunch!싱글코어CPU 의 발전한계.멀티코어 CPUConcurrency is the next major revolution in how we write software. -Herb Sutter
병행성 지향 프로그래밍Concurrency-oriented programming처음부터 병행성을 고려해서 만든 언어.공유 메모리가 없음잠금 매커니즘필요없음쉽게 병행 프로그래밍 가능
단일 할당 변수1> X.1: variable ‘X' is unbound2> X = 50.503> X = 23.** exception error: no match of right hand side value 23변수가 아니라 write-once 변수즉 한번만 bound 를 할 수 있음
패턴매칭X = 50.= 은 할당연산자가 아니라 패턴매칭연산자.오른쪽을 평가해서 그 결과를 왼쪽에 있는 패턴과 매치하라는 뜻.
왜 단일 할당이 프로그램을 더 낫게 만드는가?변수의 값을 바꿀수 있다?누가 언제 바꿨는지 깔끔하게 알기힘듬. 복잡한 잠금 매커니즘 필요.변수의 값을 바꿀수 없다?불변상태의 메모리는 read 만 가능.잠금 매커니즘이필요없다.즉 쉬운 병행 프로그래밍 가능어떻게? 프로세스 메시지 전달 방식으로.
Pure message passing language순수 메시지 전달 언어명령어 3개로병행프로그래밍 가능spawn : 프로세스 생성! (send) : 메시지 보내기receive : 메시지 받기
$ erl1> Pid = spawn(fun area:loop/0).<0.45.0>2> Pid! {rect, 6, 10}.rect : 603> Pid! {circle, 5}.circle : 78.54> Pid! {triangle, 2, 4, 5}.what is it? triangle?
area.erl-module(area).-export([loop/0]).loop()->receive		{rect, Width, Ht} ->io:format(“rect : ~p~n”, [Width * Ht]),			loop();		{circle, R} ->io:format(“circle : ~p~n”, [3.14 * R * R]),			loop();		Other ->io:format(“what is it? ~p?~n”, [Other]),			loop()	end.
Erlang processOS process 와는 다른얼랭자체process프로세스마다 mailbox 를 하나씩 가짐프로세스에 메시지를 보내면 mailbox 로 들어가고 receive 문을 평가할때mailbox 에서 메시지를 하나씩 꺼내서 처리
공유메모리 없고 잠금도 필요없으므로Easy쉬운병행 프로그래밍 가능
Erlang?병행성멀티코어분산무정지
멀티코어 프로그래밍Multicore programming쉬운 병행 프로그래밍 덕분에 멀티코어도 역시 쉽게 가능동일머신의 멀티코어 분산처리프로세스를 spawn 해서 처리하고 결과모으기
-module(pmap).-export([map/2,pmap/2]).map(_, []) -> [];   map(F, [H|T]) -> [F(H) | map(F,T)].  pmap(F, L) ->    	S = self(),	Ref = erlang:make_ref(),    Pids = map( fun(I) -> spawn(fun() -> do_f(S, Ref, F, I) end) end , L ),   	gather(Pids, Ref).   do_f(Parent, Ref, F, I) ->                          	Parent ! {self(), Ref, (catch F(I))}.   gather([Pid|T], Ref) ->   	receive		{Pid, Ref, Ret} -> [Ret|gather(T, Ref)]   	end;   gather([], _) -> [].
싱글코어 프로그래밍map(_, []) -> [];   map(F, [H|T]) -> [F(H) | map(F,T)].1> F = fun(X) -> (2 * X) end.#Fun<erl_eval.6.5634564>2> F(10).203> pmap:map(F,[1,2,3,4,5]).[2,4,6,8,10]
멀티코어 프로그래밍1> F = fun(X) -> (2 * X) end.#Fun<erl_eval.6.5634564>2> F(10).203> pmap:pmap(F,[1,2,3,4,5]).[2,4,6,8,10]process 5개가 각각 인수를 병렬로 평가
멀티코어 프로그래밍pmap(F, L) ->    	S = self(),	Ref = erlang:make_ref(),    Pids = map( fun(I) -> spawn(fun() -> do_f(S, Ref, F, I) end) end , L ),   	gather(Pids, Ref).   do_f(Parent, Ref, F, I) ->                          	Parent ! {self(), Ref, (catch F(I))}.   gather([Pid|T], Ref) ->   	receive		{Pid, Ref, Ret} -> [Ret|gather(T, Ref)]   	end;   gather([], _) -> [].
pmap:pmap(F,[1,2,3,4,5]).Pids = map( fun(I) -> 		spawn(fun() -> do_f(S, Ref, F, I) end) 	end , L ),do_fF(I)spawnpmapdo_f(Parent, Ref, F, I) ->                          	Parent ! {self(), Ref, (catch F(I))}. Parent ! 2gather([Pid|T], Ref) ->   	receive		{Pid, Ref, Ret} -> 			[Ret|gather(T, Ref)]   	end;   gather([], _) -> []. 반복
쉬운 병행프로그래밍 덕분에Easy쉬운멀티코어 프로그래밍 가능
Erlang?병행성멀티코어분산무정지
분산?Distributed Programming멀티코어 프로그래밍에서 spawn 으로 생성한 프로세스들이 동일한 머신에 있을필요없음.Erlang node 와 얼랭 표준 라이브러리를 이용
여러머신의 네트워크 분산처리Erlang node 간의 message 전달방식으로 쉬운분산처리 가능Erlang node 란 이름을 가지고 있는 Erlang runtime system이름을 가진 Erlang shell
여러머신의 네트워크 분산처리server 라는 이름의 Erlang node 실행$erl –sname server(server@serverhost) 1>쿠키각 node 는 쿠키를 한개씩 가지고있고 쿠키가 같은노드끼리만 통신가능$erl –sname client –setcookieabc(client@clienthost) 1>
-module(mod).-export([F/1]).F(X) -> 2*X.$erl –sname server(server@serverhost) 1>rpc:call(client@clienthost, mod, F, [2]).4Server Noderpc:call4F(2)Client Node$erl –sname client(client@clienthost) 1>
Erlang node와 얼랭 표준 라이브러리를 이용하여Easy쉬운분산 프로그래밍 가능
Erlang?병행성분산멀티코어무정지
무정지?멈추지 않는 서비스Server down!다른서버가 작업을 이어서 수행무정지는프로세스간의 link 기능으로 쉽게 구현가능
Process spawn내가 생성한 프로세스가 멈춰도 난 모름Pid = spawn(fun() -> … end)내가 생성한 프로세스가 멈추면 나도 멈출래Pid = spawn_link(fun() -> … end)내가 생성한 프로세스가 멈추면 내가 해결해줄께process_flag(trap_exit, true),Pid = spawn_link(fun() -> … end)
Pid = spawn(fun() -> … end)Pid = spawn_link(fun() -> … end)process_flag(trap_exit, true),Pid = spawn_link(fun() -> … end)AB
-module(fault).-export([start/0]).start() -> process_flag(trap_exit, true),spawn_link(fun() -> work() end),	loop().work() -> 	sleep(5000),	2/0.loop() ->	receive		{'EXIT',SomePid,Reason} ->io:format("system down !!")	end.sleep(T) ->	receive	after T -> true	end.
(server@host)1> fault:start().…5초후…system down !!=ERROR REPORT==== 7-Jan-2009::23:56:29 ===Error in process <0.67.0> on node 'server@host' with exit value: {badarith,[{fault,work,0}]}(server@host)2>
-module(fault).-export([start/0]).start() -> process_flag(trap_exit, true),spawn_link(fun() -> work() end),	loop().work() -> 	sleep(5000),	2/0.loop() ->	receive		{'EXIT',SomePid,Reason} ->io:format("system down !!"),start().	end.sleep(T) ->	receive	after T -> true	end.
(server@host)1> fault:start().…5초후…system down !!=ERROR REPORT==== 7-Jan-2009::23:56:29 ===Error in process <0.67.0> on node 'server@host' with exit value: {badarith,[{fault,work,0}]}…5초후…system down !!=ERROR REPORT==== 7-Jan-2009::23:56:34 ===Error in process <0.68.0> on node 'server@host' with exit value: {badarith,[{fault,work,0}]}
process link 기능을 이용하여Easy쉬운무정지 프로그래밍 가능
Hotcode swappingDynamic Code Loading 기능우리가 특정모듈의 특정함수를 호출할때항상 가장 최신 버전의 함수가 호출됨
-module(hotcode).-export([start/0]).start() -> 	spawn(fun() -> loop() end).loop() ->	sleep(1000),	Val = a:x(),io:format("a:x() : ~p~n", [Val]),	loop().sleep(T) ->	receive	after T -> true	end.-module(a).-export([x/0]).x() -> 1.
1> c(hotcode).{ok,hotcode}2> hotcode:start(a).<0.49.0>a:x() : 1a:x() : 1a:x() : 1-module(a).-export([x/0]).x() -> 1.-module(a).-export([x/0]).x() -> 2.3> c(a).{ok,a}a:x() : 2a:x() : 2
동적 코드 로딩WoW이런것도 가능
Erlang?애텀, fun, 튜플, 리스트병행성공유메모리가 없음 – 잠금필요없음 spawn, ! , receive 3개 명령어멀티코어 process 여러 개 spawn 해서 처리하고 취합분산Erlang node 와 표준 라이브러리 rpc무정지 process link
언어의 한계가 곧 자기세계의 한계이다. - 루트비히비트켄슈타인
referenceProgramming Erlang  –인사이트-http://www.gotw.ca/publications/concurrency-ddj.htm -Herb Sutter-실용주의프로그래머 –인사이트-

Erlang