함수형 프로그래밍: 두 판 사이의 차이

위키백과, 우리 모두의 백과사전.
내용 삭제됨 내용 추가됨
편집 요약 없음
Psk810 (토론 | 기여)
편집 요약 없음
6번째 줄: 6번째 줄:
함수형 프로그래밍 언어는, 특히 최초의 Hope같은 순수 함수형 언어는 상업적 소프트웨어 개발에서보다는, 학계에서 많은 관심을 받았다. 하지만 [[커먼 리스프]], [[스킴 (프로그래밍 언어)|스킴]], ISLISP, Clojure, Racket, [[얼랑 (프로그래밍 언어)|얼랑]], [[Objective Caml|OCaml]], [[하스켈]], [[스칼라 (프로그래밍 언어)|스칼라]], [[F 샤프|F#]] 같은 주요 함수형 언어들은 광범위한 조직에서 산업적이고 상업적인 어플리케이션에서 사용되고 있다. 함수형 언어는 R (통계), [[매스매티카]] (상징과 수론 수학), J, K 와 Kx 시스템 기반 (재정 시스템)에서 나온 Q, XQuery/[[XSLT]] ([[XML]]), Opal 같은 특정 영역 프로그래밍 언어(Domain Specific Language)에서도 사용되고 있다. 많이 쓰이는 특정 영역 선언 언어인 [[SQL]]과 [[Lex|lex]]/[[Yacc]]는 특히 가변값을 회피하는데 있어 함수형 언어의 일정 요소들을 사용한다.
함수형 프로그래밍 언어는, 특히 최초의 Hope같은 순수 함수형 언어는 상업적 소프트웨어 개발에서보다는, 학계에서 많은 관심을 받았다. 하지만 [[커먼 리스프]], [[스킴 (프로그래밍 언어)|스킴]], ISLISP, Clojure, Racket, [[얼랑 (프로그래밍 언어)|얼랑]], [[Objective Caml|OCaml]], [[하스켈]], [[스칼라 (프로그래밍 언어)|스칼라]], [[F 샤프|F#]] 같은 주요 함수형 언어들은 광범위한 조직에서 산업적이고 상업적인 어플리케이션에서 사용되고 있다. 함수형 언어는 R (통계), [[매스매티카]] (상징과 수론 수학), J, K 와 Kx 시스템 기반 (재정 시스템)에서 나온 Q, XQuery/[[XSLT]] ([[XML]]), Opal 같은 특정 영역 프로그래밍 언어(Domain Specific Language)에서도 사용되고 있다. 많이 쓰이는 특정 영역 선언 언어인 [[SQL]]과 [[Lex|lex]]/[[Yacc]]는 특히 가변값을 회피하는데 있어 함수형 언어의 일정 요소들을 사용한다.


함수형 스타일의 프로그래밍은 함수형 언어로 별도로 설계되지 않은 언어에서도 가능하다. 예를 들어, 명령형인 [[펄]] 프로그래밍 언어는 함수형 프로그래밍 개념을 적용하는 법을 설명하는 책의 주제이기도 했다. [[C 샤프|C#]] 3.0은 함수형 스타일의 쓸 수 있는 구문을 추가했다.
함수형 스타일의 프로그래밍은 함수형 언어로 별도로 설계되지 않은 언어에서도 가능하다. 예를 들어, 명령형인 [[펄]] 프로그래밍 언어는 함수형 프로그래밍 개념을 적용하는 법을 설명하는 책의 주제이기도 했다. [[C 샤프|C#]] 3.0은 함수형 스타일의 쓸 수 있는 구문을 추가했다.


== 역사 ==
== 역사 ==

2013년 3월 29일 (금) 12:57 판

함수형 프로그래밍은 계산을 수학적 함수의 평가로 취급하고 상태와 가변 데이타를 멀리하는 프로그래밍 패러다임의 하나이다. 명령형 프로그래밍에서는 상태를 변화시키는 것을 강조하는 것과는 달리, 함수형 프로그래밍은 함수의 응용을 강조한다. 함수형 프로그래밍은 1930년대에 계산가능성, 결정문제, 함수정의, 함수응용과 재귀를 연구하기 위해 개발된 형식체계인 람다 대수에 근간을 두고 있다. 많은 함수형 프로그래밍 언어들은 람다 계산을 발전시킨 것으로 볼 수 있다.

사실, 수학적 함수와 명령형 프로그래밍에서 사용되는 함수는 차이가 있는데, 명령형의 함수는 프로그램의 상태의 값을 바꿀 수 있는 부작용이 날 수 있다. 이 때문에 명령형 함수는 참조투명성이 없게 되어, 같은 코드이라도 실행되는 프로그램의 상태에 따라 시간마다 다른 결과값을 낼 수 있다. 반대로 함수형 코드에서는 함수의 출력값은 그 함수에 입력된 인수에만 의존하는데, 그래서 인수 x에 같은 값을 넣고 함수 f를 호출하면 항상 f(x)라는 결과가 나온다. 부작용을 제거하면 프로그램의 동작을 이해하고 예측하는데 훨씬 쉽게 된다. 이것이 함수형 프로그래밍으로 개발하려는 핵심 동기중 하나이다.

함수형 프로그래밍 언어는, 특히 최초의 Hope같은 순수 함수형 언어는 상업적 소프트웨어 개발에서보다는, 학계에서 많은 관심을 받았다. 하지만 커먼 리스프, 스킴, ISLISP, Clojure, Racket, 얼랑, OCaml, 하스켈, 스칼라, F# 같은 주요 함수형 언어들은 광범위한 조직에서 산업적이고 상업적인 어플리케이션에서 사용되고 있다. 함수형 언어는 R (통계), 매스매티카 (상징과 수론 수학), J, K 와 Kx 시스템 기반 (재정 시스템)에서 나온 Q, XQuery/XSLT (XML), Opal 같은 특정 영역 프로그래밍 언어(Domain Specific Language)에서도 사용되고 있다. 많이 쓰이는 특정 영역 선언 언어인 SQLlex/Yacc는 특히 가변값을 회피하는데 있어 함수형 언어의 일정 요소들을 사용한다.

함수형 스타일의 프로그래밍은 함수형 언어로 별도로 설계되지 않은 언어에서도 가능하다. 예를 들어, 명령형인 프로그래밍 언어는 함수형 프로그래밍 개념을 적용하는 법을 설명하는 책의 주제이기도 했다. C# 3.0은 함수형 스타일의 쓸 수 있는 구문을 추가했다.

역사

알론조 처치가 1930년대에 개발한 람다 대수는 함수에 대한 이론적 기반을 세웠다. 이것은 프로그래밍 언어가 아니라 수학적 추상화였지만, 이것은 함수형 프로그래밍의 근간을 이루었다.

처음으로 만들어진 함수형 프로그래밍 언어는 IPL이었다. 존 매카시가 만든 리스프는 훨씬 향상된 함수형 프로그래밍 언어였고, 이것은 현대적 함수형 프로그래밍의 여러 특징을 가지고 있었다. 리스프를 발전시키고 간단하게 만든 언어로 스킴이라는 것도 나왔다.

1970년대에 로빈 밀너ML을 개발하였고, 데이비드 터너미란다 프로그래밍 언어를 개발하였다. ML의 여러 "방언"이 개발되었고, 현재 가장 많이 쓰이는 방언은 OCaml이다.

1980년대에는 그동안의 함수형 프로그래밍에 대한 연구를 바탕으로 순수 함수형 언어인 하스켈이 만들어졌다.

순수한 함수

순수한 함수(pure function)란, 부작용(side-effect)이 없는 함수, 즉, 함수의 실행이 외부에 영향을 끼치지 않는 함수를 뜻한다. 따라서 순수한 함수는 스레드 안전하고, 병렬적인 계산이 가능하다.

다음과 같은 코드에서 f는 순수한 함수라고 하자.

y = f(x) * f(x);

이 때, f가 두 번 중복되는 것을 다음과 같이 최적화할 수 있다.

z = f(x);
y = z * z;

이렇게 하면, f(x)를 계산하는 과정이 두 번에서 한 번으로 줄어들지만 두 코드의 결과는 항상 같게 된다.

하지만, f가 순수하지 않은 함수인 경우에는 이러한 방식을 사용할 수 없다. 다음의 코드에서 random이 임의의 값을 주는 함수라고 하자.

y = random() * random();

함수 random은 호출할 때마다 결과가 달라질 수 있는, 즉 부수효과를 발생시키는 함수다. 따라서, 이 코드는

z = random();
y = z * z;

와는 다른 결과를 갖게 된다. 마찬가지로

y = printf("x") * printf("x");

에서 printf가 화면에 글자를 출력하는 함수라면, 이 함수는 부수효과를 발생시키며 따라서 순수한 함수라고 볼 수 없다. C의 printf 함수는 "x"가 정상적으로 출력되었느냐 여부에 따라 0이나 1 값을 반환한다. 따라서 정상적인 경우 y는 1이 되겠지만, printf 함수가 제대로 출력하지 못하는 경우 0이 될 수도 있다. 어쨌든 순수한 함수라고 볼 수 없다.

익명 함수

익명 함수(anonymous function)란, 이름이 없는 함수를 뜻한다. 전통적인 명령형 언어에서는 모든 함수에 이름이 부여되어야만 한다. 예컨대 인수를 제곱하는 함수를 C 언어로 작성한다면 다음과 같이 작성할 수 있을 것이다.

int square(int x) { return x * x; }

그러나 함수형 언어에서는 이 함수를 익명함수로 작성할 수 있다. 다음은 하스켈로 작성한 제곱 함수다.

\x -> x * x

여기서 \x의 역빗금 \은 람다 계산법의 람다를 의미한다. 위 함수를 람다 표현으로 나타내면 가 된다.

고계 함수

고계 함수(higher-order function)란, 함수를 다루는 함수를 뜻한다. 사실 함수형 언어에서는 함수도 '값(value)'으로 취급한다. 그러므로 정수 1이나 인수를 제곱하는 함수나 동등한 입장에서 다룰 수 있다. 정수를 함수의 인수로 전달할 수 있듯이 어떤 함수도 다른 함수의 인수로 전달할 수 있다. 마찬가지로 함수의 결과 값으로 정수를 반환할 수 있듯이 함수를 반환할 수도 있다.

예를 들어서 1에서 10까지 숫자로 이루어진 리스트의 각 원소를 제곱하고 싶다고 하자. 명령형 언어에서는 반복문을 이용하여 리스트를 훑어 가며 각 원소를 제곱하겠지만, 함수형 언어에서는 리스트를 다루는 고계 함수로 이를 처리할 수 있다. 다음은 하스켈을 이용하여 이를 수행한 예를 보여준다.

map (\x -> x * x) [1..10]

여기서 [1..10]은 1에서 10까지 숫자로 이루어진 리스트다. 고계 함수 map은 첫 번째 인수로 주어진 함수(여기서는 제곱을 수행하는 익명함수)를 두 번째 인수로 주어진 리스트의 각 원소에 적용한 결과 리스트를 반환한다. 위 코드를 수행하면 다음과 같은 결과를 얻을 수 있다.

[1,4,9,16,25,36,49,64,81,100]