Accumulator generator로 보는 파이썬의 특징 :: 2006/03/26 13:32

폴 그레이엄의 해커와 화가에 보면, 좋은 프로그래밍언어에 대한 특징들이 잘 설명되어 있다. 그가 생각하는 좋은 언어의 특징중에는 단순함과 강력함, 그리고 해커들이 좋아할 만한 기이함등이 있다. 공부벌레의 반란이란 챕터에 언어별로 Accumulator generator를 구현해보는 예제가 눈길을 끈다. (온라인상에서는 꽤 오래된 이야기인듯 싶다. 언어별로 구현소스를 받는 것도 더이상 안받더만...)

accumulator를 생성하는 함수를 작성하는 문제로서, n을 요청했을 때, 다른 수 i를 받아들여, n을 i만큼 증가시킨 값을 리턴하는 함수를 구현하는 것이다. (주의 할 점은 정수가 아니라 실수가 되어야 하며, 단순히 더하는 것이 아니라 누적하는 것이다.)

폴이 극찬하는 Lisp(common lisp)으로 풀면,

(defun foo (n)
(lambda (i) (incf n i)))


Ruby는 거의 유사하게

def foo (n)
lambda {|i| n += i} end


Perl

sub foo {
my ($n) = @_;
sub {$n += shift}
}


JavaScript도 다음처럼

function foo(n) {
return function (i) {
return n+=i
}
}


Python에서는 이렇게 하면 될듯하지만, 안된다.

def foo(n):
return lambda i: n+=i


물론, class 및 __call__등을 이용해서 구현할 수 는 있지만, lisp보다 복잡하다고. 폴은 무언가 복잡한것을 도입해야한다는 것을 그만큼 강력하지 않다는 의미로 보고 있다. lisp처럼 구하려면, 파이썬함수의 리턴값은 명시적으로 표현되어야 하므로, 다음처럼 해야한다. (from JuNe's code)

def foo(n):
def bar(i):
bar.value+=i
return bar.value
bar.value=n
return bar


왜 파이썬에서는 마지막 문의 리턴값을 사용할 수 없을까? 이 예제만 놓고 보면, Python이 Ruby, Perl, JavaScript 보다 못한 것이 아닌가 하는 느낌이 든다.

이것에 대해 Python Hacker들은 어떻게 생각을 갖고 있을까. IRC에서 퍼키군과의 대화에 의하면, statement가 리턴값을 가져서 다른 곳에 expression으로 재활용되는 것은 에러를 낼 소지가 많으므로, 파이썬에서는 그 방법을 쓰지 않는다고. 그것은 파이썬의 기본 원리중 하나라 앞으로도 바뀌지 않을 듯 하다고 한다.

이 부분에 대해서는 파이썬은 좀 더 명확한 방법을 취한다고 볼 수 있겠다.

Paul Prescod는 On the Relationship Between Python and Lisp의 글에서, 이 문제에 대한 좀 더 실제적인 의문을 표시했다. Accumlator generator의 역할을 수행하는 것이 리얼월드에서 함수일 필요가 있느냐는 것이다. 파이썬에서는 함수로도 객체로도 쉽게 만들어 사용할 수 있으니, 더 나은 방법을 제공하는 것이라는 이야기를 한다. 객체일 경우, 메쏘드로 분리해서 기능을 확장 할 수도 있으니까.

class Accumulator:
def __init__(self, start):
self.val = start

def incr(self, amount):
self.val += amount

def decr(self, amount):
self.val -= amount

val = Accumulator(5)
val.incr(10)
val.incr(11)
val.decr(5)


폴(이름이 같군;;)의 의견은 마치 FPOOP의 패러다임 차이를 이야기하는 듯 하다. 어쨌거나, FP, OOP의 특징을 입맛에 맞게 사용할 수 있다는 점은 파이썬이 자유로운 특징이라고 할 수 있겠다.
Trackback Address :: http://yong27.biohackers.net/trackback/194
Name
Password
Homepage
Secret