함수형 프로그래밍 1 - 함수 합성

Posted by 大山 Sun, 04 Feb 2007 14:20:00 GMT

함수형 프로그래밍이란 함수를 연산의 대상으로 삼는 프로그래밍 패러다임을 말한다. 수학의 함수를 떠올리면 되는데, 우선 다음의 예를 살펴보자.

f(x) = x + 3
g(x) = x^2
h = g * f
 

위에서 함수 h는 함수 f와 g를 합성한 새로운 함수이다. 이제 함수 h는 다음과 같게 정의된 것이나 마찬가지이다.

h(x) = g(f(x)) = (x + 3)^2 = x^2 + 6x + 9
 

루비는 객체지향 언어지만, 동시에 함수형 프로그래밍 언어이기도 하다. 이제 루비에서 함수 f와 g를 정의한 후, 이를 합성하여 함수 h를 만드는 과정을 살펴보도록 하자. 루비에서 함수를 정의할때는 lambda란 메소드를 사용한다. (여기에서 말하는 함수란 물론 Proc 객체를 말한다. 일반 메소드와 구분하기 위해 여기에서는 함수라는 표현을 사용하고 있다.)

f = lambda {|x| x + 3}
g = lambda {|x| x ** 2}
 

이제 함수 f와 g를 결합할 차례인데, 이를 위해서는 다음의 코드를 먼저 선언해 주어야 한다. [1]

class Proc
  def *(func)
    lambda {|*a| self[func[*a]]}
  end
end
 

위의 코드는 함수 간의 연산인 *를 정의하는데, 이 연산이 바로 함수를 합성하는 연산이다. (위의 코드는 Proc 객체에 * 메소드를 추가하고 있다.) 이제 루비에서 다음과 같은 코드를 작성할 수 있게 된다.

h = g * f
 

이제 irb에서 실제로 코드를 입력해보자.

>> class Proc
>>   def *(func)
>>     lambda {|*a| self[func[*a]]}
>>   end
>> end
=> nil
>> f = lambda {|x| x + 3}
=> #<Proc:0x0051d3f8@(irb):6>
>> g = lambda {|x| x ** 2}
=> #<Proc:0x0051a978@(irb):7>
>> h = g * f
=> #<Proc:0x0051ff2c@(irb):3>
>> f[2]
=> 5
>> g[5]
=> 25
>> h[2]
=> 25
 

위에서 'f[2]'는 루비에서 함수를 호출할때 사용하는 방식이다. 이 표현 대신 'f.call(2)'를 사용하는 것 또한 가능하다.

  1. Proc 클래스의 * 메소드의 구현은 Ruby Facets 라이브러리를 참고하고 있음.

관련글: 함수형 프로그래밍 2 - 커링

Posted in  | Tags ,  | 12 comments | no trackbacks

Comments

  1. 1.
    엽우 said about 1 hour later:

    코드에 오타가 있네요. ^^;

    f[2] => 5 여기서 2가 4가 되거나 5가 3이 되어야겠네요.

    마찬가지로

    h[2] => 25 여기서도 2가 4가 되거나 25가 9로 되어야 하겠네요.


  2. 2.
    大山 said about 3 hours later:

    엽우: 제가 실수를 했네요. 'f = lambda {|x| x + 1}'을 'f = lambda {|x| x + 3}'으로 수정했습니다. :)


  3. 3.
    ikspres said about 9 hours later:

    lambda는 거의 써 볼 기회가 없어서 잘 알지 못했는데. 재밌게 잘봤습니다.


  4. 4.
    정호경 said about 10 hours later:

    학교에서 함수형언어를 배운적이 있습니다. 그때 교수님이 하신 말씀이.. 프로그램언어의 지금 목표는 바로 함수형언어지만.... 아직은 상업화가 힘들다고 하신 말씀이 기억나네요... 하지만 분명 그쪽이 발전될거니까 공부해두라고 하신 말씀이 기억남니다..


  5. 5.
    다롱디리 said about 12 hours later:

    책에서 보긴했는데.. 저런 형태의 코드를 어떤 경우에 쓰면 좋을까요?? 저는 웬지 그냥 풀어쓰는것이 가독성 측면에서도 나을것 같은데.. 제목이 함수형 프로그래밍 1 이라서 아마도, 2,3편에 설명을 해주실듯 기대되긴 하는데 성질이 급해놔서.. ^^ 잘봤습니다.


  6. 6.
    大山 said about 20 hours later:

    @ikspres: 재밌으셨다니 다행이네요. :)

    @정호경: 교수님 말씀이 옳으신 것 같습니다. 최근 루비로 인해 함수형 프로그래밍, 메타 프로그래밍 등이 점차 메인스트림으로 진입하는 분위기네요. :)

    @다롱디리: 함수형 프로그래밍의 전반적인 이점은 후속글에서 다루려고 합니다. 함수 합성의 경우만 놓고 보면 함수 간의 연산을 예로 들려고 사용했구요, 수학 좋아하시는 분들은 이런 방식이 더 마음에 드실 것 같습니다만.. ;)

    함수 간의 연산이 중요한 이유는 코드 중복을 줄일 수 있기 때문입니다. 다른 함수를 리턴하는 함수를 구현할 수 있게 되면, 여러 함수에 공통적으로 들어갈 코드를 묶어낼 수 있습니다. 예를 들어 퀵소트 알고리듬을 얼개만 구현해 놓고, 두개의 값을 비교하는 연산(함수)과 결합하여 새로운 함수를 만드는게 가능해 집니다.


  7. 7.
    류종택 said 7 days later:

    글 퍼갔는데 괜찮은가요? ^^ (http://www.codeway.co.kr/board/bbs/tb.php/Ruby_Lecture/13) 괜찮다면 가끔 글 좀 퍼갈께요.

    좋은 하루 되세요!!


  8. 8.
    大山 said 7 days later:

    @류종택: 예, 퍼가셔도 괜찮습니다. 원문으로 링크 부탁드리구요. :)


  9. 9.
    김창준 said 11 days later:

    "함수형 프로그래밍이란 함수를 연산의 대상으로 삼는 프로그래밍 패러다임을 말한다."

    라고 하셨는데, 일반적으로 함수형 프로그래밍을 functional programming의 번역어로 쓴다는 점을 고려한다면, 함수를 연산 대상으로 삼는다는 것은 오히려 function-level programming에 적합한 정의 같습니다.

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

    계산이라는 것을 수학적 함수의 평가로 여기어서 상태와 자료 변경을 피하는 프로그래밍 패러다임(a programming paradigm that conceives computation as the evaluation of mathematical functions and avoids state and mutable data)


  10. 10.
    大山 said 11 days later:

    @김창준: 물론 옳으신 지적입니다. 보통 함수형 언어의 정의에는 말씀하신 내용 및 함수를 연산의 대상으로 삼는 프로그래밍 스타일이란 의미가 함께 사용되고 있습니다. 위키피디아에서도 함수형 프로그래밍이 보다 넓게는 higher-order 함수, first-class 함수, 클로저, 재귀함수 등의 지원을 의미한다고 말하고 있지요.

    개인적으로는 후자의 보다 넓은 의미에서의 함수형 프로그래밍이 더 중요다고 생각하는 편입니다. 루비와 같은 객체지향 프로그래밍 언어에서 좁은 의미의 함수형 프로그래밍은 단지 method chaining에 불과하지 않을까요? (side effects가 없는 함수 실행은 concurrent processing에 있어 이론적으로는 더 유리할 수 있지만, 아직 주요 함수형 언어에서 이를 본격적으로 구현하지는 않는 걸로 알고 있습니다.)


  11. 11.
    장보윤 said about 1 month later:

    안녕하세요 저는 미술을 전공하는 대학원생입니다 제가 공부하는 세미나 수업에서 교수님이 "정체성"이란 것에 대해 알아보자고 준비를 하려고 Google에서 정체성이란 글을 치니이 홈페이지가 나왔어요 정체성이란 글 외에도 여러개의 흥미로운 글이 많아 읽다가 글을 쓰고 갑니다 좋은 글 참 많구요 좋은 홈페이지 같네요 종종 글 읽고 갈것 같네요 ^^


  12. 12.
    大山 said about 1 month later:

    @장보윤: 좋게 봐주셔서 감사합니다. :)


Trackbacks

Use the following link to trackback from your own site:
http://beyond.daesan.com/articles/trackback/15511

Comments are disabled