Media Log

[얼랭]에 해당되는 글 1

  1. h 프로그래밍 얼랭 -조 암스트롱 3 2009.05.11
프로그래밍 얼랭 - 8점
조 암스트롱 지음, 김석준 옮김/인사이트
요즈음 회사에서 동료들과 함께 일주일에 한번씩 모여 얼랭을 공부하고 있다.

나는 언젠가는 꼭 함수형 언어를 한 번 공부해보고 싶었는데, 그 시간이 생각보다 일찍 찾아왔다.

처음 얼마간 이 책을 공부하면서는 정말 미칠 것만 같았다.
배열도 없고 자료구조에 랜덤액세스로 접근할 수도 없으며 변수에 값을 재할당 할수조차 없으니 불편함이 이만저만이 아니다.
이 모든 것을 재귀적으로 생각하고 표현해야 하는데(간단한 루프조차도), 그것은 고1때 점화식을 공부하면서 수학을 포기해버린 나에게는 참 고통스러운 일이었다.

그럼에도 불구하고 많은 훌륭한 해커들은 LISP 같은 함수형 언어를 공부하는 것이 좀 더 나은 프로그래머가 되기 위해 많은 도움을 줄 것이라고 얘기하는데(비록 실무에서 그런 언어를 사용하지 않을지라도) 나는 얼랭을 공부하면서 그것이 어떤 뜻인지 느껴보고 싶다.

우리들은 ACM 문제들을 주 마다 하나씩 풀어보고 있는데, 모임이 있는 목요일까지는 아주 고통스러운 나날들이다. 나는 마치 예전 처음 C언어를 공부할 때 Linked List를 작성하면서 코드를 썼다 지웠다 쩔쩔매던 그 시절로 돌아간 것만 같다. 구조체 안에 자신을 가르키는 포인터가 있다는 것은 나를 아주 미치게 만들었었다. 정말 그 당시와 비슷한 기분이다.

다음번 과제는 'The Cat in the Hat' 이라는 문제인데, C로 작성된 코드가 인터넷에 있어서 얼랭으로 다시 작성해봤다. 보고 그대로 옮기는 것 조차 쉽지 않다.
아직 함수형 프로그래밍에 익숙하지 않아 몇몇 부분은 마치 C로 작성한 것 같은 느낌을 준다.


-module(cat).
-export([solve/2, pow/2, gcd/2, hcf/1, result/2, f/3, g/5]).

%greatest common divisor
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, A rem B).

%power
pow(_X, 0) -> 1;
pow(X, Y) -> X * pow(X, Y-1).

%highest common factor
hcf( N ) -> hcf( N, 2, 0, [], [] ).
hcf( 1, I, P, FL, CL ) -> [ FL ++ [I], CL ++ [P] ];
hcf( N, I, P, FL, CL ) when ( N rem I ) =:= 0 -> hcf( N div I, I, P + 1, FL, CL );
hcf( N, I, 0, FL, CL ) -> hcf( N, I + 1, 0, FL, CL );
hcf( N, I, P, FL, CL ) -> hcf( N, I + 1, 0, FL ++ [I], CL ++ [P] ).

result(N, K) -> result(N, 0, K, 0, 0).
result(N, I, K, SUM_LAZYCAT, SUM_HEIGHT) when I < K ->
   result(N, I + 1, K, SUM_LAZYCAT + pow(N, I), SUM_HEIGHT + ( pow(N, I) * pow(N+1,K-I) ) );
result(N, _I, K, SUM_LAZYCAT, SUM_HEIGHT) -> [SUM_LAZYCAT, SUM_HEIGHT + pow(N,K)].

f(K, I, COUNTLIST) when I < length(COUNTLIST) ->
   A = gcd( K, lists:nth(I+1, COUNTLIST) ),
   f( A, I+1, COUNTLIST );
f(K, _I, _COUNTLIST) -> K.

g(FN, CN, I, K, N) when I < length(CN) ->
   g( FN, CN, I+1, K, N * ( pow(lists:nth(I+1, FN), lists:nth(I+1,CN) div K) ) );
g(_FN, _CN, _I, _K, N) ->
   N.

one(L) -> one(L, 0, 0).
one(L, CNT, SUM) when (L rem 2) =:= 0 -> one( L div 2, CNT + 1, SUM + L );
one(L, CNT, SUM) -> [CNT, SUM + L].    

solve( L, N ) when (L =:= 0) and (N =:= 0) -> io:format("bye~n");
solve( L, N ) when (N =:= 1) -> one(L);
solve( L, N ) ->
   [_FL, CL] = hcf( L ),
   [FN, CN] = hcf( N ),
   io:format("~w~w~w~n", [CL, FN, CN]),
   K1 = lists:nth(1, CL),
   io:format("~w~n", [K1]),
   K2 = f( K1, 1, CL ),
   io:format("~w~n", [K2]),
   K3 = f( K2, 0, CN ),
   io:format("~w~n", [K3]),
   N1 = g( FN, CN, 0, K3, 1 ),
   io:format("~w~n", [N1]),
   result( N1, K3 ).


이제 얼랭의 꽃이라고 할 수 있는 병렬 프로그래밍 부분을 보려고 하는데, 그 부분에서 많은 기법들을 얻을 수 있을 것 같아서 기대된다.

이 책은 구성이 좀 특이하다.
보통의 언어책은 변수, 제어, 루프 등이 책의 초반부에서 많은 장을 할애하는데 반해, 이 책에는 위 내용이 거의 없다. 얼랭의 특징이 그렇기 때문이다. 중요한 것은 오직 함수이다.

나는 이 책을 공부하면서 문제를 더 작게 쪼개나가는 방법을 배우고, Closure와 같은 고차함수를 능숙하게 작성 할 수 있게 되는 것이 목표이다.

하지만, 이렇게 공부하는 것은 재미있다만 만일 직장에서 프로젝트에 얼랭을 사용하라고 한다면 나는 정말이지 회사를 그만다니고 싶어질 것 같다. 하하하.