[백업][가리사니] 함수형 프로그래밍
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;
}

쉽게말해 사이드이펙트가 없다는 것은 외부의 영향을 주고받지 않는다는 뜻. 참고사항

익명함수

먼저 일급객체 라는 개념이 있으며 조건은 아래와 같다.

  • 변수나 데이터 구조안에 담을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 반환값(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를 통한)로 바꾼다.
  • 즉 재귀와 루프와의 속도차이 단점이 사라진다.
  • 좀더 추상화된 루프라고 볼 수 있다.

추신