Erlang<br />2008 아꿈사Annual Summary<br />현수명<br />soomong80@gmail.com<br />http://soomong.tistory.com<br />
30분 동안 Erlang에서 가장 중요한것들만 효과적으로 전달하자.<br />Erlang언어를 처음 접하는 사람들에게 새로운 언어의 장점을 소개함으로써 사고의 폭을 넓힐 수 있다면 성공.<br />
Erlang?<br />병행성<br />멀티코어<br />분산<br />무정지<br />
Erlang ?<br />Ericsson 에서 초기개발되어 사용<br />함수형 언어 가운데 산업에서 쓰이는 유일한 언어<br />자체 Erlang shell 지원<br />Everything is a process.<...
$ erl<br />1> 1+2.<br />3<br />2> A = 5.<br />5<br />3> X = hello.<br />hello<br />4> X.<br />hello<br />
애텀<br />불변의 값.<br />1> hello.<br />hello<br />2> rectangle.<br />rectangle<br />
fun<br />익명함수<br />F = fun(X) -> (2 * X) end.<br />인자 X 가 들어왔을때 2*X 를 수행해서 결과를 돌려주는 함수<br />결과값을 F 에 넣는것이 아니라함수자체를 F 에 bou...
$ erl<br />1> F = fun(X) -> (2 * X) end.<br />#Fun<erl_eval.6.5634564><br />2> F(10).<br />20<br />3> Double = F.<br />#Fu...
튜플<br />정해진 수의 항목을 하나의 개체로 그룹핑<br />C 의 구조체와 비슷. 익명 구조체<br />1> Rect = {rect, 10, 45}.<br />{rect, 10, 45}<br />2> {rect, ...
리스트<br />[ Head | Tail ]<br />1> L = [1,2,3,4].<br />[1,2,3,4]<br />2> [H|T] = L.<br />[1,2,3,4]<br />3> H.<br />1<br />4>...
Factorial<br />fact.erl<br />-module(fact).<br />-export([fac/1]).<br />fac(0) -> 1;<br />fac(N) -> N * fac(N-1).<br />
Quicksort<br />quicksort.erl<br />-module(quicksort). <br />-export([quicksort/1]).<br />quicksort([]) -> []; <br />quicks...
Erlang?<br />병행성<br />멀티코어<br />분산<br />무정지<br />
The Free Lunch Is Over<br />The Free Lunch?<br />The Free Performance Lunch!<br />싱글코어CPU 의 발전한계.<br />멀티코어 CPU<br />Concu...
병행성 지향 프로그래밍<br />Concurrency-oriented programming<br />처음부터 병행성을 고려해서 만든 언어.<br />공유 메모리가 없음<br />잠금 매커니즘필요없음<br />쉽게 병행 ...
단일 할당 변수<br />1> X.<br />1: variable ‘X' is unbound<br />2> X = 50.<br />50<br />3> X = 23.<br />** exception error: no ma...
패턴매칭<br />X = 50.<br />= 은 할당연산자가 아니라 패턴매칭연산자.<br />오른쪽을 평가해서 그 결과를 왼쪽에 있는 패턴과 매치하라는 뜻.<br />
왜 단일 할당이 프로그램을 더 낫게 만드는가?<br />변수의 값을 바꿀수 있다?<br />누가 언제 바꿨는지 깔끔하게 알기힘듬. <br />복잡한 잠금 매커니즘 필요.<br />변수의 값을 바꿀수 없다?<br />불변...
Pure message passing language<br />순수 메시지 전달 언어<br />명령어 3개로병행프로그래밍 가능<br />spawn : 프로세스 생성<br />! (send) : 메시지 보내기<br />r...
$ erl<br />1> Pid = spawn(fun area:loop/0).<br /><0.45.0><br />2> Pid! {rect, 6, 10}.<br />rect : 60<br />3> Pid! {circle,...
area.erl<br />-module(area).<br />-export([loop/0]).<br />loop()-><br />receive<br />		{rect, Width, Ht} -><br />io:format...
Erlang process<br />OS process 와는 다른얼랭자체process<br />프로세스마다 mailbox 를 하나씩 가짐<br />프로세스에 메시지를 보내면 mailbox 로 들어가고 receive 문을...
공유메모리 없고 잠금도 필요없으므로Easy<br />쉬운병행 프로그래밍 가능<br />
Erlang?<br />병행성<br />멀티코어<br />분산<br />무정지<br />
멀티코어 프로그래밍<br />Multicore programming<br />쉬운 병행 프로그래밍 덕분에 멀티코어도 역시 쉽게 가능<br />동일머신의 멀티코어 분산처리<br />프로세스를 spawn 해서 처리하고 결과...
-module(pmap).<br />-export([map/2,pmap/2]).<br />map(_, []) -> [];   <br />map(F, [H|T]) -> [F(H) | map(F,T)].  <br />pma...
싱글코어 프로그래밍<br />map(_, []) -> [];   <br />map(F, [H|T]) -> [F(H) | map(F,T)].<br />1> F = fun(X) -> (2 * X) end.<br />#Fun...
멀티코어 프로그래밍<br />1> F = fun(X) -> (2 * X) end.<br />#Fun<erl_eval.6.5634564><br />2> F(10).<br />20<br />3> pmap:pmap(F,[1,...
멀티코어 프로그래밍<br />pmap(F, L) ->    <br />	S = self(),<br />	Ref = erlang:make_ref(),    <br />Pids = map( fun(I) -> spawn(fu...
pmap:pmap(F,[1,2,3,4,5]).<br />Pids = map( fun(I) -> <br />		spawn(fun() -> do_f(S, Ref, F, I) end) <br />	end , L ),<br /...
쉬운 병행프로그래밍 덕분에Easy<br />쉬운멀티코어 프로그래밍 가능<br />
Erlang?<br />병행성<br />멀티코어<br />분산<br />무정지<br />
분산?<br />Distributed Programming<br />멀티코어 프로그래밍에서 spawn 으로 생성한 프로세스들이 동일한 머신에 있을필요없음.<br />Erlang node 와 얼랭 표준 라이브러리를 이용<...
여러머신의 네트워크 분산처리<br />Erlang node 간의 message 전달방식으로 쉬운분산처리 가능<br />Erlang node 란 이름을 가지고 있는 Erlang runtime system<br />이름을 ...
여러머신의 네트워크 분산처리<br />server 라는 이름의 Erlang node 실행<br />$erl –sname server<br />(server@serverhost) 1><br />쿠키<br />각 node ...
-module(mod).<br />-export([F/1]).<br />F(X) -> 2*X.<br />$erl –sname server<br />(server@serverhost) 1><br />rpc:call(cli...
Erlang node와 얼랭 표준 라이브러리를 이용하여Easy<br />쉬운분산 프로그래밍 가능<br />
Erlang?<br />병행성<br />분산<br />멀티코어<br />무정지<br />
무정지?<br />멈추지 않는 서비스<br />Server down!<br />다른서버가 작업을 이어서 수행<br />무정지는프로세스간의 link 기능으로 쉽게 구현가능<br />
Process spawn<br />내가 생성한 프로세스가 멈춰도 난 모름<br />Pid = spawn(fun() -> … end)<br />내가 생성한 프로세스가 멈추면 나도 멈출래<br />Pid = spawn_li...
Pid = spawn(fun() -> … end)<br />Pid = spawn_link(fun() -> … end)<br />process_flag(trap_exit, true),<br />Pid = spawn_lin...
-module(fault).<br />-export([start/0]).<br />start() -> process_flag(trap_exit, true),<br />spawn_link(fun() -> work() en...
(server@host)1> fault:start().<br />…5초후…<br />system down !!<br />=ERROR REPORT==== 7-Jan-2009::23:56:29 ===<br />Error i...
-module(fault).<br />-export([start/0]).<br />start() -> process_flag(trap_exit, true),<br />spawn_link(fun() -> work() en...
(server@host)1> fault:start().<br />…5초후…<br />system down !!<br />=ERROR REPORT==== 7-Jan-2009::23:56:29 ===<br />Error i...
process link 기능을 이용하여Easy<br />쉬운무정지 프로그래밍 가능<br />
Hotcode swapping<br />Dynamic Code Loading 기능<br />우리가 특정모듈의 특정함수를 호출할때항상 가장 최신 버전의 함수가 호출됨<br />
-module(hotcode).<br />-export([start/0]).<br />start() -> <br />	spawn(fun() -> loop() end).<br />loop() -><br />	sleep(1...
1> c(hotcode).<br />{ok,hotcode}<br />2> hotcode:start(a).<br /><0.49.0><br />a:x() : 1<br />a:x() : 1<br />a:x() : 1<br /...
동적 코드 로딩WoW<br />이런것도 가능<br />
Erlang?<br />애텀, fun, 튜플, 리스트<br />병행성<br />공유메모리가 없음 – 잠금필요없음<br /> spawn, ! , receive 3개 명령어<br />멀티코어<br /> process 여러 ...
언어의 한계가 <br />곧 자기세계의 한계이다.<br /> - 루트비히비트켄슈타인<br />
reference<br />Programming Erlang  –인사이트-<br />http://www.gotw.ca/publications/concurrency-ddj.htm -Herb Sutter-<br />실용주의...
Upcoming SlideShare
Loading in...5
×

Erlang

1,696

Published on

2009.01.10
아꿈사 Annual Summary 발표자료.
Erlang

Published in: Technology, News & Politics
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,696
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Erlang"

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

×