김재우∙서영민∙하용길 [email protected]

김재우 씨는 블루엣 인터내셔널의 기술 이사로 재직중이며 개발 환경과 온라인 교육 시스템을 결합 한 소프트웨어를 설계하고 있다. 소프트웨어 공학 기술이나 관련 이론을 실천하도록 만드는 것이 개발자로서의 목표. 현재 동명정보기술원과 함께 분야별 표준 교육 과정, 전문 개발자 양성 및 인증 을 위한 교육 시스템‘Theory Into Practice’를 설계하고 있으며, 인도 Vinayaka 대학 IT Parks 소프 트웨어 개발팀과 함께 기업형 솔루션 교육과정 및 소프트웨어 개발 기술을 연구하고 있다. 서영 민∙하용길 씨는 동명 정보대학교 정보기술원 교육 시스템 연구원으로 있다.

Haskell은 탄탄한 수학 이론을 바탕으로 함수를 기본 표현 수단으로 하며, 함수의 합성을 통해 문제를 풀어 나간다. 이번 호에서는 함수를 자유롭게 사용하기 위한 Haskell의 기본 지식과 이를 통해 멋지게 문제를 푸는 방법을 배워보자.


프로그래밍이란 문제를 풀어 답을 도출하는 작업이다. 그리고 프로그래밍 언어는 문제 푸는 방법을 표현하는 도구다. 문제의 성격이 A식이면 A식에 맞도록 표현하고, B식이면 B식에 맞도록 표현한다. 모든 문제를 한 가지 방식으로 풀어내려고 고집하는 것은 현명하지 않다. 다시 말해서, 한 프로그래밍 언어의 주된 표현기법만으로 문제를 풀어 내는 것 보다 문제에 맞게 여러 가지 표현 기법을 섞어 프로그래밍하는 것이 유리하다. 이런 방식을 패러다임 섞어쓰기(Multiparadigm Programming)라고 한다. Haskell과 같은 프로그래밍 언어를 배워야 하는 이유가 바로 여기에 있다.

Haskell에서 C언어 흉내를 내는 것보다 C에서 Haskell식으로 프로그램하는 것이 훨씬 어렵다. 그 이유는 언어마다 표현력의 차이가 크기 때문이다. Haskell이 C ∙ C# ∙ C++ 등과 비교할 수 없을 정도로 풍부한 표현력을 갖고 있다는 것은 말할 필요조차 없다. 하지만 그저 수단을 제공한다고 해서 모두 좋은 언어는 아니다. 예를 들어 C++가 그렇다. 언뜻 보면 C++가 Haskell 수준의 다양한 표현력을 갖고 있는 것처럼 보인다. 하지만 사실은 여러 가지 복잡한 언어 기능을 서로 다른 바탕에서 한 곳에 몰아 넣은 것뿐이다. 이와 달리, Haskell은 튼튼한 수학 이론을 바탕으로 함수를 기본 표현 수단으로 사용한다. 함수를 바탕으로 하는 프로그래밍 언어(Functional language)에서는 함수 의 성질이 수학의 그것에 가깝고, 함수 그 자체가 정수나 소수와 같은 보통 데이터일 뿐이다.

함수형 언어의 특성

함수로 프로그래밍하는 언어는 다음과 같은 세 가지 기본 특성을 갖고 있다.

첫째 다른 언어에서 볼 수 있는 변수와 같은 기능을 좋아하지 않는다. 보통 변수란 배정문으로 시간에 따라 내용물을 갈아치울 수 있는 메모리 상자와 같다. 그러나 Haskell과 같은 언어는 한번 정해진 값을 아예 바꿀 수 없도록 하는것이 기본 정책이다. 즉, 모든 표현은 바뀔 수 없는 값을 나타낸다. 이런 특성이 이상하게 보일 지 모르지만 원리를 따져보면 그렇지 않은 쪽이 오히려 잘못된 것이다. 본래 모든 식은 항상 같은 값을 나타내야 정상이고, 함수란 식에 이름을 붙인 것이므로 인자의 값이 동일하면 어떤 환경에서도 같은 값을 나타내야 한다. 이런 원칙을 따르면 우리가 쓴 코드가 기대와 다르게 동작할 가능성은 없다. 이와 같은 특성을 참조 투명성(referential transparency)이라 한다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e3098803-4284-4315-a165-b525270b67f4/_2020-02-20_10.38.10.png

둘째, 모든 식은 함수의 합성으로 표현된다. 두 함수를 하나의 함수로 붙여 더 복잡한 함수를 만들어 내는데, 이런저런 군더더기를 제외하면 이것이 함수형 언어의 유일한 기법이다. 믿기 힘들겠지만 우리가 어린 시절 배웠던 이런 단순한 기법(함수 합성, composition)이 Haskell과 같이 풍부한 표현력을 가진 언어의 기본이 된다. 이렇듯 세상의 모든 복잡한 기능은 아주 단순한 기능과 원리로 체계 있게 결합되어 만들어지는 것이다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4008c099-019b-4020-b017-c19ddc789771/_2020-02-20_10.38.44.png

셋째, 함수는 기본 데이터다. 즉, 객체지향에서 객체가 특별한 데이터가 아니듯 함수를 쓰는 언어에서는 함수가 그와 같은 역할을 한다. 수학의 이치로 따지면 자연스럽고 당연한 얘기다. 당연히 함수는 함수의 인자가 될 수 있고, 더하거나 뺄 수 있는 값이며,식을 계산한 결과도 함수일 수 있다. 보통 이런 특징을 고차 함수(Higher-order Functions)라고 부르는데, 이 용어 때문에 이 기능이 특수하고 이질적인 표현 수단으로 오해받는 경우가 많다. 다시 말하지만 함수는 값이다. 우리가 쉽게 접할 수 있는 다른 많은 언어들이 오히려 잘못된 것이다.

딱딱하고 뜬구름 잡는 얘기는 이쯤에서 접고, 실제 프로그래밍을 하면서 차근차근 알아보자. 지난 호의 내용이 낯설고 어렵다는 반응이 와 이번에는 조금 반복되는 내용을 더해서라도 쉽게 쓰려고 노력했다. 우리에게 널리 알려지지는 않았지만, 함수를 써서 문제를 푸는 기법에 익숙하지 않은 프로그래머에게 Haskell과 같은 좋은 언어를 소개하는데 목적을 두었다.