원본 본문으로 이동하기

함수형 프로그래밍

박용서 - 함수형 프로그래밍의 장점 부작용(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를 통한)로 바꾼다. - 즉 재귀와 루프와의 속도차이 단점이 사라진다. - 좀더 추상화된 루프라고 볼 수 있다. 추신 - 본래 모나드도 추가 설명할 예정이 였지만 짧게 설명하기 어려운 개념임으로 자바스크립트 실습 위주 강의로 작성하였습니다. - 참고 : https://gs.saro.me/#!m=elec&jn=725 - 이론