2007년 08월 25일
[erlang] 함수, 함수, 함수.
erlang에서도 haskell등과 같이 함수의 선언을 합니다. 함수선언은 일반적인 패턴매칭등과의 식과는 다르게 반드시 소스코드파일을 따로 작성하여 컴파일/로딩을 거쳐서 사용하는것이 일반적입니다.
보통의 패턴매칭과 구분하기 위하여 '->' 기호를 사용합니다. 기호의 좌변에는 함수의 이름과 그 인자들을 나열해주고, 우변에는 그 식을 적어줍니다.
<code>
double(N) -> N * N.
</code>
좌변의 경우 패턴매칭을 이용하여 선언을 달리할 수 있습니다.
<code>
len([]) -> 0;
len([Hd | Tl]) -> 1 + len(Tl).
</code>
위에서 볼 수 있듯이 len/1의 경우 그 인자에 대해서 패턴매칭을 사용해 그 인자값에 따라 다르게 평가한다는 선언을 하고 있습니다. 이렇게 한 함수에 대해 여러가지 선언을 패턴매칭을 사용하여 할 경우 각 선언끼리 ';'을 이용하여 분리하고 그 끝에는 역시 '.'을 찍어줍니다. 이렇게 패턴매칭을 이용하여 대부분의 경우 조건분기등의 필요성을 없앨 수 있습니다.
또한 같은 모듈에 속한 같은 이름의 함수라도 그 인자가 다르면 둘은 완전히 다른 선언을 갖습니다. 이는 함수를 식별할때 arity을 적어주는것으로 구분합니다.(export나 import 선언에서 함수명뒤에 /n와 같이 숫자를 적어주는것.)
예를 들어 다음은 서로 다릅니다.
<code>
foo(N) -> ....
foo(N, M) -> ....
</code>
함수의 선언식 내부에서 콤마(,)을 이용하여 여러개의 식을 평가할 수 있는데 이 경우 함수의 평가값은 맨마지막 평가값을 기준으로 합니다.
<code>
f() -> 1,2,3;
...
%% 대화모드에서...
> f().
3
</code>
다른 언어에서 lambda function, anonymous function, closure등으로 불리는 익명의 함수를 만드는 방법도 제공합니다.
<code>
> Fsquare = fun(N) -> N * N end.
...
> Fsquare(4).
16
</code>
그리고 다음처럼 익명함수에 대해서도 패턴매칭을 적용할 수 있습니다.
<code>
> F_how_many = fun([]) -> none; ([_]) -> one; ([_, _]) -> two; ([_, _, _]) -> three; ([_ | _]) -> many end.
...
> F_how_many([]).
none
> F_how_many([1,2,3]).
three
> F_how_many([484,3,1,2]).
many
...
</code>
마지막으로 함수선언은 가드(guard)표현을 포함할 수 있습니다. 이는 패턴매칭만으로 나타내기 힘든 상황(값의 타입이나 대소관계등...)을 추가적으로 패턴매칭처럼 기입하여주는 역활을 할 수 있습니다.
<code>
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
</code>
위의 코드에서 보듯이 when절 뒤에 조건식이 추가됨을 알 수 있습니다.(나머지는 패턴매칭과 같이 표현하면 됩니다.) 또한 가드표현은 콤마(,)를 사용하여 여러개를 지정할 수 있는데, 한 선언에 대해서 여러개의 가드식을 줄 수 있지만, 이중에 하나만 true라면 그 선언을 선택합니다.
<code>
is_tuple_or_list(X) when is_tuple(X), is_list(X) -> true;
is_tuple_or_list(X) -> false.
</code>
또한 가드식의 내부에서는 부수효과(side-effect)가 제한되므로 다음과 같은 조건을 만족하는 식들만 가드식으로 사용할 수 있습니다.
* atom -- 언제나 true로 평가
* 다른 상수(혹은 바인딩된 변수) -- 언제나 false로 평가
* BIFs(built-in functions)나 guard predicates에 대한 호출
* 단말(term)값 끼리의 비교, 산술연산, 불리언연산, short-circuit boolean expression
여기서 허용되는 BIF와 guard predicates에 대해서는 레퍼런스를 참조하시길.
보통의 패턴매칭과 구분하기 위하여 '->' 기호를 사용합니다. 기호의 좌변에는 함수의 이름과 그 인자들을 나열해주고, 우변에는 그 식을 적어줍니다.
<code>
double(N) -> N * N.
</code>
좌변의 경우 패턴매칭을 이용하여 선언을 달리할 수 있습니다.
<code>
len([]) -> 0;
len([Hd | Tl]) -> 1 + len(Tl).
</code>
위에서 볼 수 있듯이 len/1의 경우 그 인자에 대해서 패턴매칭을 사용해 그 인자값에 따라 다르게 평가한다는 선언을 하고 있습니다. 이렇게 한 함수에 대해 여러가지 선언을 패턴매칭을 사용하여 할 경우 각 선언끼리 ';'을 이용하여 분리하고 그 끝에는 역시 '.'을 찍어줍니다. 이렇게 패턴매칭을 이용하여 대부분의 경우 조건분기등의 필요성을 없앨 수 있습니다.
또한 같은 모듈에 속한 같은 이름의 함수라도 그 인자가 다르면 둘은 완전히 다른 선언을 갖습니다. 이는 함수를 식별할때 arity을 적어주는것으로 구분합니다.(export나 import 선언에서 함수명뒤에 /n와 같이 숫자를 적어주는것.)
예를 들어 다음은 서로 다릅니다.
<code>
foo(N) -> ....
foo(N, M) -> ....
</code>
함수의 선언식 내부에서 콤마(,)을 이용하여 여러개의 식을 평가할 수 있는데 이 경우 함수의 평가값은 맨마지막 평가값을 기준으로 합니다.
<code>
f() -> 1,2,3;
...
%% 대화모드에서...
> f().
3
</code>
다른 언어에서 lambda function, anonymous function, closure등으로 불리는 익명의 함수를 만드는 방법도 제공합니다.
<code>
> Fsquare = fun(N) -> N * N end.
...
> Fsquare(4).
16
</code>
그리고 다음처럼 익명함수에 대해서도 패턴매칭을 적용할 수 있습니다.
<code>
> F_how_many = fun([]) -> none; ([_]) -> one; ([_, _]) -> two; ([_, _, _]) -> three; ([_ | _]) -> many end.
...
> F_how_many([]).
none
> F_how_many([1,2,3]).
three
> F_how_many([484,3,1,2]).
many
...
</code>
마지막으로 함수선언은 가드(guard)표현을 포함할 수 있습니다. 이는 패턴매칭만으로 나타내기 힘든 상황(값의 타입이나 대소관계등...)을 추가적으로 패턴매칭처럼 기입하여주는 역활을 할 수 있습니다.
<code>
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
</code>
위의 코드에서 보듯이 when절 뒤에 조건식이 추가됨을 알 수 있습니다.(나머지는 패턴매칭과 같이 표현하면 됩니다.) 또한 가드표현은 콤마(,)를 사용하여 여러개를 지정할 수 있는데, 한 선언에 대해서 여러개의 가드식을 줄 수 있지만, 이중에 하나만 true라면 그 선언을 선택합니다.
<code>
is_tuple_or_list(X) when is_tuple(X), is_list(X) -> true;
is_tuple_or_list(X) -> false.
</code>
또한 가드식의 내부에서는 부수효과(side-effect)가 제한되므로 다음과 같은 조건을 만족하는 식들만 가드식으로 사용할 수 있습니다.
* atom -- 언제나 true로 평가
* 다른 상수(혹은 바인딩된 변수) -- 언제나 false로 평가
* BIFs(built-in functions)나 guard predicates에 대한 호출
* 단말(term)값 끼리의 비교, 산술연산, 불리언연산, short-circuit boolean expression
여기서 허용되는 BIF와 guard predicates에 대해서는 레퍼런스를 참조하시길.
이 글과 관련있는 글을 자동검색한 결과입니다 [?]
- [erlang] 기본 자료형. by 아겔
- [erlang] "hello, world" 소스 뜯어보기 + 팩토리얼. by 아겔
- [erlang] operations by 아겔
- C 포인터, 확실히 알자(4) - 함수와 포인터 by 시즈하
# by | 2007/08/25 02:12 | erlang -- nine 9's | 트랙백




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]