수학의 함수와 프로그래밍에서의 함수는 모두 '함수'라는 이름을 공유하지만 상당히 다른 특징을 갖는다. 이에 대해 알아보자.

[1]

수학의 함수는 참조 투명성(Referential Transparency)를 갖는다. 무슨 말이냐면, 어떤 함수에 대해서, 인자만 같다면 항상 같은 값으로 evaluate된단 말이다. 예컨대 f(x) = x + 5라면 f(0)은 5로 항상 evaluate되며, f(0)을 5로 항상 대체 가능하다. 사실 수학에서의 함수 정의가 "정의역 집합의 원소 x를 정확히 하나의 공역 집합의 원소 y로 대응되는 관계"임을 생각하면 자명하다고 할 수 있다.

 

하지만 프로그래밍에서는 참조 투명성이 항상 지켜지는 것은 아니다. 가장 쉽게 떠올릴 수 있는 예로, 전역 변수를 사용하는 함수를 생각해 볼 수 있다. 다음의 c함수를 보자.

 

1
2
3
4
5
int global;
 
int sum(int x){
    return x + global;
}
cs

sum(0)에 대해서 리턴값이 유일하게 결정되는가? 전역 변수 global 값에 의해서 얼마든지 달라질 수 있음을 쉽게 확인할 수 있다. 즉 sum(0)이 0일 수도, 그 외의 값일 수도 있으므로 sum(0)을 항상 같은 값으로 evaluate 혹은 대체할 수 없다. 

 

물론 프로그래밍의 함수가 참조 투명성을 가질 수 없는 것은 아니다. 함수 구현을 통해 얼마든지 가질 수 있는 특성이며, 아예 함수형 언어처럼 참조 투명성을 강제하는 것도 가능하다.

 

[2]

프로그래밍의 모든 함수의 인자는 가질 수 있는 값이 유한하다. 좀 더 정확히 표현하자면, 프로그래밍의 함수의 인자는 항상 유한집합이다. int를 예로 들면 32비트 시스템에서 오직 2^32가지의 인풋을 가질 수 있을 뿐이다. long long이나 bigint 등의 더 큰 자료형을 사용하더라도 인풋 가짓수가 유한하다는 데에는 변함이 없다. 이는 프로그래밍의 함수는 유한한 메모리를 갖고 유한한 시간 내에 종료되어야 하기 때문이다. 반면 수학의 함수는 무한 집합에 대해서도 얼마든지 정의될 수 있다. f(x) = x + 2를 x는 자연수로 정의하면 이미 인자가 무한 집합이다.

 

또 한 가지, 프로그래밍에서 진정한 의미의 실수(Real number)는 존재할 수 없으므로, float이나 double등도 한정된 인풋을 가지며 마찬가지로 2^bits가지의 인풋이 존재할 수 있다. 즉 프로그래밍의 함수는 가산 집합(countable set)에 대해서만 정의될 수 있다. 반면에 수학에서의 함수는 실수나 복소수 등의 비가산 집합(uncountable set)에 대해서도 얼마든지 정의될 수 있다.

 

[3]

마지막으로, 수학에서는 공집합이 아닌 집합 -> 공집합(즉 리턴값이 없다.)으로 대응되는 함수를 정의할 수 없지만, 프로그래밍에서는 얼마든지 가능하다. 리턴 값이 void인 함수들이 여기에 해당한다.

 

[4]

(뇌피셜 문단)

사실 애당초 프로그래밍에서 함수란 이름은 잘못되었다. 즉, 애당초 비교될 대상이 아니인데 처음에 이름을 잘못 지었기 때문에 이런 혼동이 발생한다. 프로그래밍에서 함수란 단순히 subroutine 혹은 computational procedure에 불과하다. 물론 초기 프로그래밍 언어의 함수는 수학 함수를 모방하여 만들어졌지만, 현대 컴퓨팅 아키텍처(=튜링 머신)상의 한계 때문에 수학의 함수와 동일할 수 없다. 위의 [2]가 이에 해당한다. 또한 편의상의 이유로 다른 특징을 갖는 경우도 있다. 위의 [3]이 이에 해당한다. [1]은 기본적으로 편의상의 차이점이지만 관점에 따라선 컴퓨팅 아키텍처 상의 한계로 볼 수도 있겠다.

 

 

Reference

[1] https://stackoverflow.com/questions/3605383/what-is-the-difference-between-functions-in-math-and-functions-in-programming

+ Recent posts