[백업][가리사니] 함수형 프로그래밍
other
이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.
함수형 프로그래밍의 장점
부작용(side-effect)이 없다.
- 정확한 단위 테스트에 유리하다.
- 쓰래드에 안전하다.
- 위 장점이 멀티코어에서 더 빠르게 처리되기 좋다. 재사용이 쉽고 조합이 쉽다
- 예를들어 람다식 같은 경우 해야할 일을 명확하고 간결하게 전달 할 수 있다.
- 또한 람다를 통해 만들어진 함수를 조합할 수 있다.
함수형 프로그래밍의 단점
꼬리재귀 최적화가 되어있지 않은 언어에서 사용시 단점들이 있다.
- 반복문에 비해 속도가 느리다.
- 스택을 잡아먹기 때문에 반복이 많아질 경우 최악의 경우 스택오버플로 오류를 뱉을 수 있다. 함수형 언어가 쓰래드-병행의 근본적인 문제를 해결해 주지는 않는다.
- 언어적 제약으로 좀 더 안전하게 도와주는 것이다.
순수함수 (pure function)
- 동일한 인자를 넣었다면 언제나 동일한 결과를 반환 하는 함수.
- 부작용(side effect)이 없어야 하며 때문에 참조에 투명한 함수.
부작용(side effect) 예제1
- 외부의 객체를 읽음 / 참조에 불투명
int s1(int x) { // 외부참조를 사용한다. // globalValue 에 따라 x 값이 변경됨. return globalValue * x; }
부작용(side-effect) 예제2
- 외부의 객체를 변경 / 참조에 불투명
int s2(int x) { // 외부에 값을 저장한다. : 참조에 불투명 globalValue = x; return x; }
시간적 부작용(Temporal side effects)
- 외부의 객체를 변경하지 않음 / 외부참조에 투명 / 지역참조에 불투명
- “일반적으로 순수함수의 범주에는 들어감” 정확히는 타협. 아래 “참고사항” 부작용 참고.
- 명령에 대한 시간적(이 문맥으로 임시가 아닌 시간으로해석) 부작용만 존재.
int ts(int x) { // 일시적으로 로컬 변수 y나 i를 의 값을 변경하고있다. // 위키백과엔 sleep에대해서도 나와있지만, 필자는 이건 논쟁사항이라고생각함. // 왜냐하면 일부 언어 (예: 자바)에선 sleep이 c만큼 안전하지 않음. 외부의 영향을 많이 받음. int y = x; for(int i = 0 ; i < 10000 ; i++) { y++; } // 이 함수는 외부의 영향을 주거나 받지 않는다. return y; }
순수함수 : 참조에 투명
int pf(int x) { return x + 1; }
쉽게말해 사이드이펙트가 없다는 것은 외부의 영향을 주고받지 않는다는 뜻. 참고사항
- 순수함수 : https://en.wikipedia.org/wiki/Pure_function
- 부작용 : https://en.wikipedia.org/wiki/Side_effect_(computer_science)
- 참조투명성 : https://en.wikipedia.org/wiki/Referential_transparency
익명함수
먼저 일급객체 라는 개념이 있으며 조건은 아래와 같다.
- 변수나 데이터 구조안에 담을 수 있다.
- 파라미터로 전달 할 수 있다.
- 반환값(return value)으로 사용할 수 있다.
- 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
- 동적으로 프로퍼티 할당이 가능하다. 이 일급객체의 조건을 만족하는 함수를 일급함수라고 한다. 익명 함수는 일급 함수의 요소중 하나로 지원리스트는 아래와 같다.
- 일급함수 지원 언어 목록 : https://en.wikipedia.org/wiki/First-class_function
- 익명함수 지원 언어 목록 : https://en.wikipedia.org/wiki/Anonymous_function 즉 익명함수는 일급객체가 하는 일을 부분 혹은 전부 할 수 있는 함수이다.
- 많이쓰이는 예로는 람다식이 있다.
특징
고차함수
- 함수를 인자로 받거나 반환하는 함수.
- 함수를 받아서 실행하거나, 반환하거나 할 수 있다.
- 클로저를 만드는 함수도 고차함수에 속한다. 꼬리재귀 꼬리재귀 최적화(tail call optimization)를 지원하는 언어에서 처리해주는기능.
- 재귀의 스택을 무한정 쌓는 문제를 해결할 수 있다.
- Data Flow / Control Flow Analysis 를 이용 컴파일 과정중에 꼬리재귀를 루프형태(언어마다 다르지만 goto를 통한)로 바꾼다.
- 즉 재귀와 루프와의 속도차이 단점이 사라진다.
- 좀더 추상화된 루프라고 볼 수 있다.
추신
- 본래 모나드도 추가 설명할 예정이 였지만 짧게 설명하기 어려운 개념임으로 자바스크립트 실습 위주 강의로 작성하였습니다.
- 참고 : /2016/05/25/%EB%B0%B1%EC%97%85-%EA%B0%80%EB%A6%AC%EC%82%AC%EB%8B%88-Monad-(%EB%AA%A8%EB%82%98%EB%93%9C)-Javascript-%EB%A1%9C-%EC%84%A4%EB%AA%85.html