함수 프로그래밍이 주목받는 세 가지 이유

 
By 2012년 7월 4일 

최근 들어서 함수 프로그래밍이 새롭게 주목을 받고 있는 이유는 세 가지가 있다. 첫 번째는 멀티코어 CPU를 장착한 컴퓨터가 대세가 되면서 멀티쓰레딩을 지원하는 소프트웨어가 필요하게 되었다는 점이다.

무어의 법칙에 따르면 컴퓨터에서 사용하는 반도체 회로 성능은 대략 18개월마다 2배로 빨라진다. 2000년대 중반까지만 해도 이러한 무어의 법칙은 어김없이 관철되었다. 이것은 곧 시간만 흐르면 (프로그래머가 아무런 노력을 기울이지 않아도) 모든 소프트웨어 성능이 저절로 두 배로 향상되었다는 사실을 뜻한다. 그렇지만 무어의 법칙은 컴퓨터 칩의 속도가 결코 빛보다 빨라질 수 없다는 사실에 대해서는 아무런 말도 하지 않았다.

물리적인 한계에 부딪힌 CPU 회사들은 하나의 칩이 더 빠른 속도를 갖도록 만드는 수직적 전략을 포기하고, 그 대신 여러 개의 칩이 병렬적으로 동작을 하도록 만드는 수평적 전략을 채택했다. 멀티코어 CPU가 등장하게 된 배경이다. 하나의 CPU가 여러 개의 어플리케이션을 실행하던 환경에서 하나의 어플리케이션이 여러 개의 CPU를 이용하는 환경으로 바뀐 것이다.

이전 환경에서 “멀티쓰레딩” 코드는 여러 개의 쓰레드가 하나의 CPU를 가장 효율적인 방식으로 공유하도록 만드는데 초점을 기울였지만, 멀티코어 환경에서 “멀티쓰레드” 코드는 이제 어플리케이션이 동작하는 동안 놀고 있는 CPU가 없도록 만드는데 초점을 기울인다. CPU 성능이 무어의 법칙을 따라 수직적으로 향상되던 시절에는 소프트웨어 성능이 하드웨어 성능 개선과 더불어 향상되었지만, CPU 성능이 수평적으로 향상되는 시절에는 소프트웨어가 멀티코어를 활용하는 동시성 프로그래밍을 적극적으로 지원하지 않으면 성능이 향상되지 않는다. 어브 써터(Herb Sutter)같은 사람은 이러한 현상을 두고 “공짜 점심은 끝났다”라는 유명한 말을 남기기도 했다.

동시성 코드를 작성하는 것은 어렵다. 프로그래밍 실력이 아무리 뛰어난 사람이라고 해도 정확성을 100% 보장하는 동시성 코드를 작성하는 것은 불가능하다. 브라이언 괴츠의 Java Concurrency in Practice는 현대의 프로그래머들에게 동시성 코드를 작성하는 것이 왜 어려운지, 어느 정도로 어려운지, 어째서 잠금(lock)이나 세마포(semaphore) 같은 동시성 프로그래밍의 어셈블리 언어를 사용하는 상황을 피해야 하는지 잘 보여주었다.

자바나 C# 같은 명령형(imperative), 객체 지향적 언어를 이용해서 동시성 코드를 작성하는 것이 지극히 어려운 이유는 여러 가지가 있는데, 이러한 언어에서는 객체 상태나 데이터 값이(프로그래머가 특별한 노력을 기울여서 일부러 막지 않는 한) 기본적으로 변경 가능(mutable)하다는 사실이 가장 결정적인 이유다. 객체 상태나 데이터 값은 여러 쓰레드가 공유하는 경우가 많다. 데이터가 공유된다는 사실 자체는 별로 문제가 아니다. 하지만 공유되는 데이터가 변경 가능하면 비극이 시작된다. 데이터의 공유와 변경 가능성(mutabiliy)은 죽음의 칵테일이다.

함수 프로그래밍이 새롭게 주목을 받는 이유는 바로 이 지점에 있다. 함수 프로그래밍에서는 모든 데이터가 기본적으로 변수가 아니라 상수다. 즉, 값이 변경 불가능(immutable)하다. 값이 변경되지 않는 상수는 아무리 많은 쓰레드가 동시에 접근하더라도 동시성과 관련된 문제를 야기하지 않는다. 그들은 잠금(lock)을 통해서 보호될 필요도 없고, CPU의 레지스터에 저장되는 캐시 값과 관련된 가시성(visibility) 문제를 일으키지도 않는다. 함수 프로그래밍은 멀티코어 CPU 환경에서 발생하는 동시성 프로그래밍과 관련된 문제를 예컨대 객체지향 언어보다 뛰어난 멀티쓰레딩 구조물을 통해서 해결하는 것이 아니라, 그러한 구조물의 필요성 자체를 제거하는 방식으로 해결한다는 점에서 (오래된)혁명이다.

최근에 와서 함수 프로그래밍이 주목을 받는 이유의 두 번째는 코드의 간결함이다. 객체지향 언어를 오랫동안 사용해온 프로그래머라면 전략패턴(strategy pattern)이나 방문자 패턴(visitor pattern)과 같은 종류의 디자인 패턴에 친숙할 것이다. 이러한 패턴은 유용하지만, 함수 프로그래밍의 입장에서 보면 우격다짐에 가깝다.

반드시 필요한 논리와 추상을 추려내서 우아하게 표현하는 것이 아니라, 패턴 자체를 위한 인터페이스를 정의하고, 인터페이스를 구현하는 내용을 작성하고, 인터페이스에 정의된 메쏘드를 미리 정해진 방식에 따라서 호출하는 과정에는 본질적이지 않은 부수적이고 장식적인 코드가 너무 많기 때문이다.(앤더스 하일스버그 같은 사람은 비본질적인 코드를 세레모니(ceremony)라고 표현한다. 세레모니는 적을수록 좋다.)

함수 프로그래밍에서 사용하는 중요한 개념인 커리(curry), 부분 어플리케이션(partial application), 모나드(monad)와 같은 기법은 지극히 간결하고 우아한 함수의 구성(composition)을 가능하게 해준다. 이러한 개념에 대해서는 나중에 더 자세히 설명하도록 하겠다. 자바에 비해서 한 발 앞서 람다(lambda)나 클로저(closure)같은 구조물을 지원한 C#은 (자바에 비해서)함수 프로그래밍 언어의 특징을 많이 가지고 있다.

도메인 특정 언어(DSL: Domain Specific Language)로 분류되는 LINQ는 C# 내부에 존재하는 일종의 함수 프로그래밍 언어다. 프로그래머로 하여금 “어떻게”가 아니라 “무엇”에 집중하게 만들어 준다는 점에서 LINQ는 그 자체로 함수 언어로 봐도 무방하다. 이런 맥락에서 보자면 프로그래머들이 흔히 사용하는 SQL 언어도 함수 언어다. (데이터베이스 서버에 SQL 질의문을 보낼 때, 그 구문이 실행되는 동안 발생할 지도 모르는 멀티쓰레딩 문제를 고민한 적이 있는가? 아마 없을 것이다. “어떻게”는 데이터베이스 서버가 알아서 할 일이고 프로그래머는 “무엇”에만 집중할 수 있기 때문이다.)

함수 프로그래밍이 주목을 받는 세 번째 이유는 자바와 C# 같은 기존의 언어가 발전모드에서 관리모드로 접어들면서 프로그래밍 언어와 관련한 새로운 패러다임이 요구되는 현실과 관련이 있다. 자바의 JVM이나 C#의 .NET CLR은 특정 언어에 국한되지 않는 일종의 플랫폼 역할을 하기 때문에 이러한 플랫폼 위에서 다양한 언어적 실험이 이루어지고 있다는 현실과도 무관하지 않다.

루비나 파이선 같은 동적 언어에서 스칼라나 F#과 같은 함수 언어에 이르기까지 매우 다양한 스펙트럼의 언어가 JVM과 .NET 플랫폼을 대상으로 실험되고 있다. JVM에서 동작하는 언어가 자바만 있는 것으로 알고 있는 사람이라면 당장 위키피디아에서 List of JVM languages 항목을 검색해보기 바란다. JVM 위에서 얼마나 많은 언어가 동작하는지 알면 깜짝 놀랄 것이다. 함수 프로그래밍 패러다임은 객체지향 패러다임의 뒤를 이을 새로운 패러다임을 발견하기 위한 전반적인 실험과 암중모색의 와중에 하나의 강력한 대안으로 주목을 받고 있다.

[관련글]프로그래밍 세계의 새로운 버즈워드-함수 프로그래밍
요즘 컴퓨터 프로그래밍의 세계에서는 단연 ‘함수 프로그래밍(functional programming)’이 주목을 받고 있다. 함수 프로그래밍은 프로그래밍 세계의 ‘버즈워드’인 셈이다. 함수 프로그래밍은 새로운 패러다임이 아니다. 함수 프로그래밍의 역사를 짚으려면 거의 1950년대로까지 거슬러 올라가야 할 정도다. 함수 프로그래밍 패러다임은 80년대 무렵에 C 언어의 절차적(imperative) 패러다임의 뒤를 잇는 차기 패러다임의 자리를 놓고 객체지향(object-oriented)패러다임과 자웅을 겨루었다.

페이스북으로 댓글을 남기실 수 있습니다.
THE AUTHOR
임백준 Baekjun.Lim@gmail.com | 한빛미디어에서 『누워서 읽는 퍼즐북』(2010), 『프로그래밍은 상상이다』(2008), 『뉴욕의 프로그래머』(2007), 『소프트웨어산책』(2005), 『나는 프로그래머다』(2004), 『누워서 읽는 알고리즘』(2003), 『행복한 프로그래밍』(2003)을 출간했고, 로드북에서 『프로그래머 그 다음 이야기』(2011)를 출간했다. 현재 맨해튼의 바클리스은행에서 월스트리트 금융규제를 위한 도드-프랭크 법안에 따르는 중앙청산소 시스템을 C# 언어로 개발하고 있다. 뉴저지에서 아내, 두 딸과 함께 살고 있다.
 
  • gimmesilver말하길

    SQL이 함수형 언어의 일종이다라…RDB가 Relation을 바탕으로 하고 있고 이산 수학의 관점에서 볼 때 함수는 Relation의 일종이니 관련이 아주 없진 않지만 그래도 SQL이 단지 상태를 갖지 않는다는 점 때문에 함수형 언어라는 건 오해를 살 수 있는 다소 지나친 확대 해석이 아닌가 싶습니다.

  • philnet말하길

    대학원 AI 수업에서 LISP으로 과제 하며서 학을 뗐었는데, 개발 환경으로 이맥스를 이리저리 쓰면서 LISP을 다시 재밌게 보고 있습니다.

    사이드 이펙트가 없어서 맵-리듀스에 적용하기 용이해서 생산성이 높을 수 있다는 글을 어디서 본 적이 있는데요, 같은 이유로 멀티 코어 시스템에서 유리할 거란 말씀이 새삼 와 닿네요.

    그리고 말씀대로, JVM 위에서 돌아가는 함수 언어들이 정말 생각보다 많네요.

    좋은 글 잘 봤습니다.

  • 임백준말하길

    gimmesilver님. SQL이 LISP이나 해스컬 같은 수준의 함수언어라는 의미가 (당연히) 아니라 프로그래머가 프로그래밍을 할 때 “어떻게”가 아니라 “무엇”에 집중할 수 있도록 만들어 준다는 맥락에서 보았을 때 SQL도 함수언어의 특징을 갖는다는 의미였습니다. C#의 LINQ도 마찬가지입니다. 그 자체로 F#이나 스칼라 같은 수준의 함수 언어는 아니지만 함수 구성(composition) 같은 함수 프로그래밍의 특징을 잘 지원한다는 점에서 함수 언어적 특징을 가지고 있죠. C와 C++, 자바, C#과 같은 절차적(procedural), 명령형(imperative) 언어의 패러다임에 익숙한 (저 자신을 포함한) 사람들에게는 함수 프로그래밍의 기본 개념을 잡는 것이 쉬운 일이 아닙니다. 이럴 때 SQL은 유용한 비유로 사용될 수 있습니다. SQL이 함수 언어라고 주장하려는 것은 아니었는데 너무 짧게 쓰다보니 그렇게 들릴 수도 있었네요. 앞 문장에서 설명하고 있는 “맥락”에서 보았을 때 SQL도 그러한 함수 언어적 특징을 가지고 있다는 정도의 말이었습니다. 사실 함수 언어의 순혈주의자들이 보았을 때는 객체와 변경 가능한 값(mutable values)의 사용으로 마구 더렵혀진 F#이나 스칼라조차 함수 언어로 보지 않을 지도 모릅니다. 반대편 끝의 스펙트럼에서는 C#을 함수 언어로 보는 사람도 있지요. 무엇이 함수 언어고 무엇이 함수 언어가 아닌가를 가리는 논쟁은 희미한 개념을 뚜렷하게 만들어 준다는 점에서 생산적입니다. 좋은 지적 감사합니다.

    philnet님. LISP이라니.. 너무 재밌겠습니다. 저처럼 프로그래밍으로 먹고 살아야 하는 사람은 LISP처럼 재밌는 언어를 공부할 기회가 잘 없네요. 저도 꼭 한 번 공부해 보고 싶습니다.

  • gimmesilver말하길

    //임백준
    네 제가 우려했던 점은 함수형 언어의 장점을 얘기하다 보니 모든 좋은 건 다 함수형 언어의 특징이다 식의 결론이 나는 것이었습니다.

    이를 테면, 위에 글이나 답변에서 언급하신 ‘어떻게’가 아니라 ‘무엇’에 집중할 수 있게 만드는 것은 제가 생각하기에 함수형 언어의 특징이라기 보다는 언어 디자인의 문제가 아닐까 싶습니다.
    예를 들어 1~10 까지 합을 구할 때 절차형 언어는
    sum = 0
    for (i = 1; i <= 10; ++i)
    sum += i
    라고 하지만 함수형 언어는 sum = reduce (+) [1..10]
    이라고 표현할 수 있겠죠. 그리고 이 때문에 흔히 함수형 언어는 '합산'이라는 행위를 표현하는데 집중하게 되지만 절차형 언어는 목적에는 불필요한(for 문 처리같이 '어떻게'하느냐라는) 작업을 표현하느라 사고를 낭비하게 된다고 비판할 수 있습니다.

    그러나 이건 함수형 언어의 장점이 아니라 디자인의 문제라 생각합니다. 왜냐하면 객체 지향 언어에서도 sum = [1..10].sum() 이라고 얼마든지 디자인이 가능하기 때문이죠.
    따라서 프로그래밍의 직관성과 언어의 패러다임은 다른 문제인 것 같습니다.

    물론 이런 세세한 부분을 제외하고 전반적인 논지에 대해서는 임백준님의 글에 대해 충분히 공감합니다.