처음에 프로그래밍에 입문했을때 제일 큰 충격은 다음의 한 줄 이었다.
i = i + 1;
돌아버린거냐? 라는 말이 절로 나왔다.
아무리 그래도 컴퓨터의 근본은 수학으로 알고 있었는데...
어떻게 맨 처음부터 나오는 명령이 저런거라니 라는 생각밖에 안들었다.
시간이 흘러 최근 JavaScript를 접하면서 함수형 프로그래밍이라는 새로운 개념을 접했는데,
찾아보니 수학적인 철학?이 많이 차용된 것 같은 것 같아서 조금은 기뻤다.
사실 함수형 프로그래밍이더라도 저 선언은 사용한다.
그렇지만 이제 익숙해져버려서 거부감이 있거나 그러진 않고.. 몇가지 수학적인 성질이 들어가 있길래
복습겸 정리해보자 한다.
1. 순수 함수(Pure Function)를 지향
기본적으로 수학에서의 함수와 그간의 프로그래밍 언어에서의 함수는 차이가 있었다.
import random
x = random.random()
y = x ** 2
위와 아래는 확실한 차이가 있다.
전자는 x값이 어떤 값이든 동일한 x값에 대한 동일한 y값을 얻는다.
반면, 후자의 경우, 일정한 값을 받기 위해 사용하는 seed라는 개념이 있긴 하지만
기본적으로 random 함수에 파라미터를 주지 않고 실행한다면 계속해서 다른 값이 나온다.
프로그래밍에서 순수 함수(Pure function)란, 기본적으로 수학에서의 함수와 같은 정의를 가진다고 생각하면 된다.
정의역 X에서 Y로의 relation의 집합, 그리고 x1 = x2 이면 f(x1) = f(x2) 이라는 함수의 기본 성질 말이다.
그러나 순수함수가 이 성질을 항상 지키지는 않는다.
사실, 프로그래밍에서 엄밀히 말하는 순수 함수란 side-effect가 없는 함수를 의미한다.
side-effect가 없다는 말은 함수 외부에 영향을 주지 않는 함수를 의미한다.
아래의 예시를 보자.
let x = 1;
function referentiallyTransparent (x, y) {
return x + y;
}
function hasNoSideEffect(y) {
return x + y
}
두 번째 함수가 side-effect가 없는 함수, 외부에 영향을 주지는 않는 함수이다.
저렇게 된 함수를 실행해서 y를 파라미터로 넘겨줬을때 x+y로 반환을 해도 이 함수는 외부에 어떤 영향도 주지 않는다.
(메모리에 변화를 주거나, I/O에 변화를 주지 않는다는 것이다.)
그러나 이 함수는 위에서 말하는 수학과 같은 함수의 성질을 가지지는 않는다.
이 성질을 참조투명성(referentially transparent)라고 부른다.
정리하자면, 순수함수란 side-effect가 없는 함수를 말한다.
그렇기에 참조 투명성을 보장하지는 않는다.
다만 함수형 프로그래밍 패러다임에서는 기본적으로는 참조 투명성을 가지기 위해 노력한다.
그러면 참조 투명성을 지향하는 이유는 뭘까?
- Testability & Debugging; 같은 값을 반환해주니 테스트(unit test)에 용이하고,
문제가 생기면 이를 참조하는 함수만을 확인하면 해결되기 때문이다. - Memoization ; 캐싱에 용이하다.
2. 익명 함수를 제공
굳이 함수를 정의 하지 않아도 바로 정의하고 사용할 수 있는 함수를 말한다.
setList = [(2, 3, 1, 5), (3, 1), (1, 2, 3)]
setList.sort(key = lambda x: len(x)) # [(3, 1), (1, 2, 3), (2, 3, 1, 5)]
const numList = [1, 2, 3, 4];
numList.forEach((value) => {
console.log(value + 1); // 2, 3, 4, 5 출력 됨
}
)
위의 예시처럼 파이썬의 람다 함수나 JavaScript의 arrow 함수 같은 것이 그 예이다.
3. 고계 함수 성질을 가진다.
다른 말로, 함수형 프로그래밍에서의 함수는 일급 객체로서의 역할을 한다는 것이다.
더 풀어 쓰자면,
- 함수가 변수로 할당이 되고
- 함수를 함수의 파라미터로 넘길 수 있고
- 함수가 함수를 반환할 수 있다는 것이다.
따라서 JavaScript 에서의 함수는 일급 객체이며, 사실상 일급 함수이고, 고계 함수의 성질을 가진다.
추가적으로 JavaScript는 함수형 프로그래밍 언어이지만, 객체 지향적인 언어이며
Java는 객체 지향 프로그래밍 언어이지만, 함수형 프로그래밍을 지향한다고 볼 수 있겠다.
결론
이 글에서는 함수형 프로그래밍의 핵심 개념들인 순수 함수, 익명 함수, 고계 함수를 다루었다.
글을 정리하면서 함수형 프로그래밍의 패러다임이 유지 보수성에 뛰어날 수 있겠다고 많이 느꼈다.
출처 https://en.wikipedia.org/wiki/Functional_programming
Functional programming - Wikipedia
From Wikipedia, the free encyclopedia Programming paradigm based on applying and composing functions In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarati
en.wikipedia.org
'연재작 > 프로그래밍 언어' 카테고리의 다른 글
Java - Optional 뽀개기 (1) (0) | 2024.10.11 |
---|---|
Java - Stream 뽀개기 (2) (2) | 2024.10.06 |
Java - Stream 뽀개기 (1) (feat. 함수형 인터페이스) (0) | 2024.10.06 |
monad 패턴, optional, promise, stream (1) | 2024.10.05 |
Java Collection, Map에 내재되어 있는 수학 (0) | 2024.09.27 |