Java에서 함수형 프로그래밍 사용해보기 - [1 : 함수형프로그래밍?]



안녕하세요. CX사업본부 MD태태입니다.

JDK8이 릴리즈된지는 이제 꽤 오래되었지만, 바쁘다는 핑계로 적용해 보지 못하다가 최근 새로운 프로젝트에서 JDK8을 적용하게 되었습니다. 그러면서 자연히 Java 8이 제공하는 새로운 인터페이스들과 기능들을 살펴보게 되었습니다. Java8이 릴리즈 되면서 가장 큰 변화는 역시 Lambda식에 관한 것 일텐데요, Lambda식은 객체지향언어인 Java에 함수형 프로그래밍의 개념을 대입하기위한 인터페이스입니다. 저도 이미 오래전부터 함수형 프로그래밍이라는 말은 많이 들어보았지만 실제로 관심을 가지고 내용을 살펴보거나 사용해보지는 못하고 있었지요. 그래서 이번기회를 통하여 함수형프로그래밍의 개념과 장점, 단점을 알아보고 실제로 적용해보기로 했습니다. 그러한 과정에서 경험한 것과 배운것들을 몇회에 걸쳐 포스팅하며 공유해 보도록 하겠습니다.

이번 포스팅은 그 첫번째로, 함수형 프로그래밍이 무엇인지에 대하여 정리해 보았습니다.


  • 함수형 프로그래밍

한국어 위키피디아에서는 함수형프로그래밍을 다음과 같이 정의하고 있습니다.

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

역시 개념에 대한 설명은 얼른 이해하기에는 좀 어렵지요. 위의 설명을 조금 더 직관적으로 정리한 문구가 있습니다.

Functional programming is programming without assignment statements.

Robert C. Martin이 자신의 블로그에 함수형 프로그래밍에 대해 설명하며 언급한 내용입니다. 직역해 본다면 '함수형 프로그래밍은 대입문이 없는 프로그래밍'이라는 뜻인데, 사실 언뜻 이해가 되지는 않습니다. 대입문이 없다는것은 변수를 선언한고 그에 대한 값을 지정해주지 않는다는 많인데 어떻게 대입문이 없는 프로그램 작성이 가능한 것일까요?

위 코드처럼 우리는 아주 간단한 프로그램을 작성할 때도 변수를 선업합니다. 내부적인 동작을 보면 메모리에 할당된 i라는 Integer변수의 값을 반복해서 변화시키면서 로직을 실행하는 것이지요.

하지만 함수형 프로그래밍에서는 이러한 개념을 사용하지 않는다고 합니다. 아주 간단한 함수형 프로그래밍의 코드모양을 살펴보면 아래와 같습니다.

위 코드는 이해를 돕기위해 실제 동작여부와 상관없이 Java형태로 작성한 코드입니다. Java개발자라면 이 간단한 코드에서 무언가 이상한 부분을 발견하실 수 있을 것입니다. take함수의 2번째 매개변수로 print함수가 넘어가고 있습니다. 실제 Java개발자들이 본다면 위 코드는 사실 말도 안되는 코드이지요. 맞습니다. 아마 위와 같이 Java코드를 작성한다면 동작하지않고 컴파일 에러를 출력할 것입니다.

이것이 바로 함수형 언어의 또다른 특징입니다. 이 특징을 함수형 언어에서는 함수를 일급 객체(First-class object)로 간주한다고 표현하고 있습니다. 일급 객체는

1. 변수나 데이터 구조안에 담을 수 있다.

2. 파라미터로 전달 할 수 있다.

3. 반환값(Return value)로 사용할 수 있다.

4. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.

다음과 같은 조건을 만족하는 객체입니다. 그런 조건이라면 위의 코드가 말이 됩니다. 또한 변수를 선언하지 않는 프로그래밍 방식도 설명이 가능합니다.

즉, 함수를 선언할 때 그 함수에 전달되는 매개변수가 같다면 함수는 언제, 어떤상황에서 호출되어도 같은 값을 반환하는 함수를 선언하여 그 함수들을 이용해서 프로그래밍 하는 것입니다. 이를 '참조 투명성(Referential Transparency)'라고 합니다. 위키피디아에서도 함수형 프로그래밍에 대한 개념적 설명 바로 다음에 참조투명성에 대한 설명이 나옵니다. 위키피디아에 따르면 명령형 함수는 프로그램의 상태값을 바꿀 수 있다고 설명하고 있습니다, 이는 다시 말하면 우리가 익숙하게 변수를 선언하여 메모리에 할당한 값이 계속 바뀔 수 있음을 의미하지요. 그리고 함수형프로그래밍에서는 그런 변화가 없다. 즉, 메모리에 한 번 할당된 값은 새로운 값으로 변할 수 없다고 설명하고 있습니다. 다음은 위키피디아 함수형 프로그래밍 페이지 개념문단 바로 다음에 나오는 참조투명성에 대한 설명입니다.


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

함수형 프로그래밍에서 이 '참조투명성'은 아주 중요한 개념으로 언급되고 있습니다. 참조투명성은 함수가 개발자가 의도하지 않은 값을 반환하지 않음을 의미합니다. 이는 어떠한 환경, 어떠한 조건에서도 같은 함수를 호출하면 항상 같은 값을 반환한다는 것을 의미하며, 우리가 멀티코어 환경이나 멀티쓰레드 환경의 개발을 할 때 항상 골머리를 앓는 Race condition등의 문제에 대한 고려비용이 현격히 줄어든다는 것을 의미합니다. 즉, 프로세서들이 메모리영역을 동시에 사용해도 아무런 문제가 없음을 의미하지요. 이것이 함수형 프로그래밍 언어 사용자들이 이야기하는 함수형 프로그래밍의 가장 큰 장점입니다.

정리하자면, 함수형 프로그래밍은 함수를 1급 객체로 간주하여 파라미터로 넘기거나 반환값(Return Value)로 사용할 수 있으며 참조투명성을 지키는 형태로 작성하는 프로그래밍 기법입니다.

당연히 이 내용이 함수형 프로그래밍에 대한 모든것은 아니지만 이정도가 함수형 프로그래밍에 대한 대략적인 개념 입니다. 함수형 프로그래밍이라는 개념 자체가 저에게 생소하기 때문에 더 깊이 설명하지 못했고 어쩌면 틀린 부분이 있을 수도 있습니다. 그렇지만 큰 틀에서의 함수형 프로그래밍에 대한 개념은 크게 다르지 않을것입니다.

Java 커뮤니티에서는 Java 8 이전부터 함수형 프로그래밍 방식에 대한 여러가지 의견들이 있었습니다. Java도 언어의 발전방향을 받아들여 함수형 프로그래밍기법을 적극적으로 활용해야 한다는 입장과, Java의 철학과 객체지향적인 프로그램 구조에서 함수형 프로그래밍을 사용했을 때 많은 위험성이 생길 수 있기 때문에 지양해야 한다는 의견으로 갈라지기도 했습니다. 그러나 많은 객체지향, 명령형 프로그래밍 언어들도 이미 함수형 프로그래밍의 개념을 차용했고, Java도 8부터는 함수형 인터페이스를 제공하고 있습니다. 현재의 함수형 프로그래밍이 가진 장점이 분명히 존재한다는 의미이고, 객체지향언어에서도 충분이 그 장점들을 살린 개발이 가능하다는 의미일 것입니다.

앞으로의 포스팅에서는 Java가 제공하는 함수형 인터페이스를 활용해서 프로그램을 직접 작성해 보고 그에 따른 장점과 단점을 개인적인 생각과 더불어 공유해 보겠습니다.




참조 :

https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D - 위키피디아

https://pragprog.com/magazines/2013-01/functional-programming-basics - Functional Programming Basics

http://blog.8thlight.com/uncle-bob/2013/01/02/FPBE2-Whys-it-called-functional.html - Why's it called functional?

http://cafe.elharo.com/programming/java-programming/why-functional-programming-in-java-is-dangerous/ - Why functional programming in java is dangerous

https://justhackem.wordpress.com/2014/06/19/why-functional-programming-in-java-is-not-dangerous/ - Java의 함수형 프로그래밍이 생각보다 위험하지 않은 이유

http://icoon22.tistory.com/263 - 함수형 프로그래밍

New Multi-Channel Dynamic CMS