콩의 전설

사내 라이브러리를 쓸 일이 있어 문서를 보다 main class 가 아닌 것은 모두 빈즈 란 이름을 붙인 것을 보았다.

삽질계에 빈즈 란 용어가 쓰이기 시작한 것은 모델 1 (이라 쓰고 JSP 에 다 때려 박는다 라고 읽는다) 방식에서 웹에서의 MVC, 일명 모델 2 방식에 대해 갑론을박이 벌어지면서 라고 기억한다.
모델 2란 이름으로 봐선 일정한 방식을 특징지어 말하는 것 같지만, 실질적으로 JSP는 View 역할만으로 한정하고 Controller 와 Model 역할을 분리한 (혹은 분리할 수 있는 것처럼 보인) 수많은 방법론이 모델 2 라고 자칭했었다. 그중 당장 생각나는 것만 해도 커스텀 태그 라이브러리, 스트러츠, 웹 매크로, 티, 벨로서티 등등 그야말로 백가쟁명의 시대가 따로 없었다.
이렇게 딱히 이것이다 라고 정의된 것이 없다 보니 악화가 양화를 구축한다고 Beans 란 이름만 붙여서 클래스를 만들고 JSP 에서 호출하면 은근슬쩍 모델 2 입네 하는 것들도 있었고 사람들도 대충 뭉뚱그려 쳐 주는 현상이 있었다.

본디 JavaBeans 스펙은 캡슐화를 지키면서 introspection 을 하지 않고 외부 클래스가 내부 속성에 대한 접근자를 알아내기 위한 규약을 정의하고 있다. 이때만 하더라도 세상은 모두 component 들의 조합으로 이루어 질 줄 알았고 (혹은 기대했고) 이를 위해서는 component 에 대한 조합을 (손으로 할 수는 없으니) 할 Tool 이 component 의 속성에 접근하는 것이 필요했기 때문이었다.
하지만 세상사가 다 그렇듯 자바 데스크탑 컴포넌트는 글자 그대로 쫄딱 망했고 JavaBeans 스펙도 묻히는 가 싶더니 (약간 생뚱맞게도) 웹에서의 MVC 에서 데이터 구조를 표현하는데 부활하게 되었다 라고 쓰고 싶었는데 사실은 그렇지 않다.

첫 문장에서 썼듯 원래의 의도와는 전혀 상관없게도 데이터 표현 (getter/setter 를 쓴다) 에 비즈니스 로직까지도 얼렁뚱땅 덧붙여진 클래스면 대충 Beans 란 이름을 붙여 쓰는 경우가 허다하다. 솔직히 말하자 당최 Beans 란 postfix 를 왜 붙이는지 모르겠다.
까 놓고 보면 getter/setter 는 있되 JavaBeans 스펙에서 말하는 규약도 따르지 않는다면 굳이 이름에다 Beans 를 붙일 아무런 이유가 없다.
나는 이것이야말로 누가 어떤 의도로 시작한 지는 모르지만 대충 이렇게 해 왔으니 따라 한다는 관습에 지나지 않는다고 생각한다.

지금 자신의 class 에 Beans 라는 이름이 붙은 클래스들이 있다면 다른 것으로 이름을 바꾸어 보면 좋겠다. 예를 들면 A4Beans, B4Beans 가 있다면 A4Adzuki, B4Adzuki 로 바꾸어 놓고 보자 - Adzuki 는 팥이다.
결론적으로 아무런 차이가 없다면 그저 Beans 를 클래스를 구분하기 위한 postfix 로 사용한 것이며 만약 PrinterBeans 까지 있었다면 구분자의 효과도 없었을 것이다.

다시 말하자.
Beans 라는 이름을 쓰고 싶다면 최대한 (그 의도대로 쓰는 사람이 드물다 할지라도) 스펙에서 정의된 형식을 유지하는 것이 좋겠다.
비즈니스 로직과 뒤엉키는 것이 불가피하다면 그냥 Beans 라는 postfix 를 붙이지 말고 절약된 5자를 좀 더 친절한 클래스명으로 하는데 시간을 들이는 것이 정신 건강에 좋을 성싶다.

Posted by eoh

2009/12/30 23:15 2009/12/30 23:15
, , ,
Response
No Trackback , No Comment
RSS :
http://endofhope.com/tc/rss/response/17

Dynamic language 유감

예전 회사에서는 C 와 Java 가 사내 개발 언어였다.
근자에 들어 Dynamic 한 속성을 중시하는 script 언어들이 널리 회자되면서 Java 언어는 사용하기에 불편한 언어군에 속하는 것으로 여겨지지만, 예전에 C 로 개발하는 부서와 협업을 하다보면 Java 로 개발하는 것은 어느 정도 거저 먹는구나 란 느낌을 언제나 받았다.
전 직장에서는 수행시간에  critical 한 제품은 C로 개발하는 것이 당연시 되고 생산성과 유지 보수 및 향후 확장성이 더 중요한 제품은 Java 가 선택되었다.
나는 Java 를 사용하여 Middleware 를 만드는 부서에 속해 있었고, 나를 비롯한 구성원들의 화두는 Java 의 생산성과 확장성을 유지하면서도 C 만큼의 Performance 를 어떻게 하면 낼 수 있을까 였다.
그동안 Native thread 에 대한 지원, Garbage collector 의 성능 향상, Native io 지원, Hot spot VM 혹은 JIT compiler 등 Java 언어 및 가상머신은 그 성능에 있어 괄목할만한 발전을 이루어 냈고 우리는 이러한 발전을 오롯히 제품에 반영하려고 노력함으로써, 내심 이정도 Performance 를 내는 Middleware 를 확장성과 안정성 및 유지 보수의 용이성을 전혀 희생하지 않고서 C로 구현한다는 것은 어떠한 경우라도 수지타산이 맞지 않을 것이다란 생각을 가졌다.
그리고 해당 제품과 Java 로 만들어진 다른 Middleware 들이 Mission critical 한 영역에까지 저변을 넓히는 것을 목격하면서 우리의 생각이 틀리지 않았다는 확신을 가질 수 있었다.

예전 포스트에서도 언급한 바 있듯 지금은 Ruby 를 사용한 web application 을 개선하는 일을 하고 있다.
혹자는 Java 언어에 비해 생산성이 3배에서 10배까지 높다는 script 언어를 실무에서 사용할 기회를 얻은 것을 행운이라고 생각할지도 모르겠다.
일반적으로 Script 언어는 구닥다리? 컴파일 언어에 비해 생산성이 높다고 한다. 특히 Ruby 의 경우 여러 설문 결과 및 개인적인 경험담들을 쉽게 찾을 수 있다.
하지만 내가 이 글을 쓰는 이유는 과연 Ruby 의 생산성 신화는 과연 타당한 것인지 의문이 생겼기 때문이다.

지금 파악된 바로는 내가 소속된 부서에서 맡은 서비스는 일반적인 RDBMS 에 데이터를 저장하고 web page 를 서비스하는데 그치지 않고 SMS, MMS 문자 전송이나 OPEN API 지원까지 포함하다보니 코드의 라인 수가 10만 라인을 훌쩍 넘는다. 그리고 개발 인력의 수가 10여명 정도이다.

내가 느끼는 애로사항은 Ruby는 지나치게  Dynamic 하게 사용하기가 쉽다는 것이다.
예를 들어 코드 상에서 특정 메써드가 어디에 정의되어 있는지 알고 싶을 때 grep 이나 ack 로 이름 검색을 해야 한다는 건 좀 지나치지 않는가? 그렇게 대충 찾은 후엔 해당 위치를 일일이 파악하면서 과연 어느 정의가 내가 찾던 그 정의인지 확인해야 하는 작업을 해야 한다는 건 집중력을 흐트러뜨리는 데는 이것만한 것이 없었다.
이것만 해도 슬슬 어깨가 결려오는데 아무리 찾아도 안 찾기던 경우가 2가지 있었다. 하나는 클래스명과 메써드 명을 - 그것도 변수명에 넣어서 넘긴 후 introspection 을 사용하여 runtime 시에 동적으로 클래스 인스턴스를 생성한 후 메써드를 호출하는 경우였고 두번째는 method_missing 을 썼는데 parameter 로 넘긴 문자열의 prefix 가 무엇인가에 따라 prefix 를 뗀 나머지 문자열을 이름으로 가진 메써드를 호출하는 경우였다.
이러한 경우 여러 사람이 작업하다 보면 본의 아니게 이름공간이 훼손되는 경우가 생길 가능성이 짙다. Java 로 예를 들자면 Date 객체가 있는데 이게 대체 java.util.Date 인지 java.sql.Date 인지 모호한 경우가 되겠다.
Strictly typed 언어인 경우 compile 시에 이게 모호하다는 경고와 함께 발견 가능하다. IDE 를 쓰는 경우 ambiguity 여부를 바로 알려주기도 한다. 그런데 Ruby 에서 이런 일이 발생하면 이 에러가 동작시에나 검출된다. 이미 배포해서 서비스 하는 도중에 이런 일이 발생했다는 걸 알면 등에 식은 땀이 흐를 것이 뻔하고 미리 좀 알수 있었으면 얼마나 좋을까 란 생각이 절로 날 것이다.

물론 이러한 Dynamic 언어들을 옹호하는 측에선 작성자의 완전한 자유를 보장하는 것이 무엇보다 중요하기 때문에 의도적으로 그러한 가능성을 열어 둔 것이며, 이러한 오류는 테스트 케이스를 촘촘하게 준비함으로써 피할수 있다 라고 주장한다. 적절한 시간적인 여유가 있는 경우에는 그럴 수도 있겠다. 그런 여유를 가지고 구현하고 있는 곳을 알면 나에게도 좀 알려주었으면 한다.
테스트 케이스를 잘 잡으면 모든 오류를 방지할 수 있다 란 이야기가 어느 정도 먹혀들어가고 있다는 사실은 아직 Ruby 로 현실적인 상황에서 Mission critical 한 시스템은 구축된 적이 없다는 반증으로 밖엔 생각할 수 없다.

생산성의 정의를 협의로 생각한다면 한정된 시간에 얼마나 많은 기능을 구현할수 있는가에 대한 척도라고 할 수 있겠다. 이러한 점에서 3배, 10배 이야기도 나오는 것일 게다.
10사람이 할 일을 한 사람이 동일한 시간에 한다면 10배 이런 식일 것이다.
자 여기서 곰곰히 생각해 보자. 동일한 능력을 가진 사람이 사물을 보고 행동할 때 특정 패러다임을 다른 패러다임으로 바꾸었더니 10배 더 많은 Output을 내려면 어떻게 해야 할까?
내 생각에는 어느 한 패러다임이 굉장히 규격화된 경우라서 많은 기능을 생각없이 찍어낼 수 있으면 가능하다고 생각한다. 아마도 Active* 계열을 쓰는 Rails 프레임워크가 대표적인 경우일 것이다.
그런데 이건 좀 이상하지 않은가?
우리는 굉장히 자유로운 표현력을 가진다. 그런데 우리는 굉장히 높은 생산성도 가진다.
아무리 생각해도 이 두 문장은 미묘한 위화감을 준다.
아마도 두번째 문장 뒤에
- 단 우리가 미리 결정한 방식을 따르는 경우에는
이런 구절이 덧붙으면 적절할 것 같다.

생산성은 위에서 말하는 협의의 뜻으로 생각할 것이 아니라 향후 유지 및 보수의 유이성까지 포함한 광의로 사용되어야 한다. 그리고 설정보다 관례란 이야기에서 상당히 심한 강제의 냄새를 맡는다면 내가 지나치게 성마른 것일까?
표현력을 추구하자면 파악이 어려워져 유지보수가 어려워지고 (협의의) 생산성을 극대화 하자면 정해진 관례를 따라야만 한다.

Ruby 의 생산성에 대한 올바른 평가는
  1. Mission critical 한 부분에서
  2. 상당히 많은 수의 사람이 협업하며
  3. 복잡하고 많은 기능을 구현하는
3가지 조건을 만족하는 프로젝트의 결과를 본 후에야 납득할 만한 결론이 나올 것 같다.

Posted by eoh

2009/10/31 04:44 2009/10/31 04:44
, , , ,
Response
No Trackback , No Comment
RSS :
http://endofhope.com/tc/rss/response/10

자연스러움에 대하여

하나의 프로그래밍 언어에 어느 정도 익숙해 지면 필요없이 번잡하다고 느껴지는 API 들이 눈에 거슬리기 마련이다. 그래서 특정한 작업을 수행하는데 있어 제공되는 API 들을 사용하여 일일히 나열하기보다 스스로 작성한 서브루틴들을 사용해 깔끔함을 추구하게 된다.
하지만 조금 더 경험을 쌓다 보면 결국 서브루틴으로 묶는 것으로는 한계에 부딛치는데, 대표적으로는 약간 다른 일들을 하는 여러 비슷한 서브루틴들을 만들어야 하는 상황이 닥치는 것이다.
단순하게는 서브루틴들을 더 잘게 쪼갠 원자적 서브루틴들의 조합으로 만들면 되겠지 란 생각이 들겠지만, 이를 직접 해 보면 결국은 언어의 문법과 거진 1:1 로 매치해야 된다는 것을 알아채곤 바로 포기하게 된다.
이 정도에 다다르면 해당 언어에서 제공되는 문법 자체가 자연스럽게 느껴지지 않게 되어 내가 문법을 설계한다면 더 "자연스러운" 문법을 만들어낼수 있을 것이라고 생각한다.

프로그래밍 언어에서 자연스러움이란 무엇일지 생각해보았다.
먼저 내가 가지고 있는 책의 한 부분을 인용한다면
Ruby에 관한 오래된 문구 중에는 '놀라운 최소의 법칙' 이라는 게 있다. Ruby 커뮤니티에서 막연히 공유되고 있는 Ruby다운 사고방식으로, Ruby는 이 생각에 비추어 자연스럽게 행동해야 한다는 것이다.
- 출처 입문자를 위한 루비 - 유구이 저
라고 말하고 있다.
자연스럽다는데 막연하다니. 내가 느끼기엔 아무래도 왜? 자연스러운지에 대한 해답은 되지 않을 것 같고 따라서 자연스럽지 않다고 생각하는 사람에게 이렇기 때문에 자연스럽다 라고 주장할 수는 있어도 설득하기엔 근거가 약해 보인다.
(2..100).each do |candidate|
  sqrt = Math.sqrt(candidate)
  factor_found = (2..sqrt).any? {|i| candidate%i == 0}

  if factor_found then
    print "#{candidate}는 합성수\n"
  else
    print "#{candidate}는 소수\n"
  end
end
코드를 처음부터 읽어 내려가며 의미가 통하는 것에 주목하기 바란다.
- 출처 입문자를 위한 루비 - 유구이 저
라고 말하면서 "알고리즘이나 소프트웨어 개발의 보편적인 개념을 설명하는 사람들은 코드 예문으로 Ruby를 이용하게 되었다." 라고 쓰고 있다.
그런데 내겐
  1. 일단 아무런 사전 예고 (선언) 없이 나온 변수 sqrt 와 Math.sqrt 가 좀 헷갈린다.
  2. (2..sqrt).any?{..} 의 모습을 보건대 2 부터 sqrt 까지 돌면서 {..} 을 수행하고 그 결과가 any? 인지 - 즉 참인 것이 있는지 여부를 따지는 것으로 겨우 짐작할수는 있겠는데, 이게 자연스러운것과 무슨 관련이 있는 건지는 모르겠다.
  3. if factor_found then ... 를 보고 나서야 factor_found 가 boolean 값이구나 라고 짐작이 가능했다. 솔직히 말하면 if 조건 으로 factor_found 가 쓰인 것 을 보고서야 (2..sqrt).any?{..} 문장이 boolean 을 반환하는지 짐작할 수 있었다. 물론 ? 가 끝에 붙은 메써드는 boolean 을 반환하도록 미리 약속되어있다 라고 알고 있다면 쉽게 이해 되겠지만 어쨋든 한번에 이해하지 못한 내겐 결국 자연스럽지 않았다는 결론에 이르게 된다.
자. 자연스러운가?
루비 문법을 아는 사람에게는 아주 자연스러울 것이다.
하지만 내겐 그렇게까지 자연스럽지는 않다. 왜냐면 나는 루비 문법에 익숙하지 않으니까.
그러면 루비 문법에 익숙하면 자연스러워질 것인가?
까놓고 말해보자. 익숙하면 뭐든 다 자연스럽게 느껴진다. ;-)
다시 말하자면 자연스럽다는 것은 너무나 개인적인 감정인 것이다.

내가 이 코드 조각이 생각난 것은 "간만에 세미나를 가서 CUDA 에 관한 발표를 들었다" 는 아는 사람의 글을 보고 나도 시간을 내서 CUDA 를 사용해 보고 싶은데 왠지 CUDA 를 이용해 소수 찾기 알고리즘을 구현해 볼까 란 생각을 했기 때문이다.

모든 일들이 다 그렇듯 어른의 사정은 복잡하고도 미묘하다.
소수 찾기도 위에서 인용한 "자연스러운" 방법으로 접근하면 당연히 경쟁력이 없다.
그러면 루비로 어른스러운 알고리즘을 사용하여 소수찾기를 해 보면 어떨까?
과연 그 어른스러운 알고리즘도 "자연" 스러울까?
굳이 소수 찾기 같은 오덕스러운 분야는 제외한다면, 일반적인 프로그래밍이 얼마나 "자연" 스러울지는 내가 아직 루비 경험이 일천하여 판단하기 어렵다.

Posted by eoh

2009/09/26 04:44 2009/09/26 04:44
,
Response
No Trackback , No Comment
RSS :
http://endofhope.com/tc/rss/response/7

개발자와 프로그래머

언제부터인가 개발자 라는 말이 자연스레 프로그래머가 자신을 지칭하는 말이 되어버렸다.
일단 놈 者 자가 붙은 직종 치고 대우받는 게 드물다는 것을 한탄하는 어느 기자 의 말은 차지하고서라도, 나는 왠지 이 개발자 란 어휘가 마음에 들지 않는다.

20세기 말 업계에는 패턴 광풍이 불어친다.
1920년대 시카고도 아닐진대 누구나 갱들의 전설적인 이야기를 했다.
그들의 총구 앞에 모든 문제들은 손을 들 수 밖에 없으며 클라이언트들은 돈을 창구 앞에 쌓아놓고 있으니, 패턴을 따라 그 돈을 가져가기만 하면 되는 것 처럼 보였다.
물론 대부분의 추종자들은 전설의 갱들처럼 그렇게 쉽게 문제들을 털진 못했지만 이건 단순히 패턴을 잘못 적용했기 때문이므로 문제들에게 사로잡힌 불운한 추종자들은 죽음의 행진 중에서도 패턴에 대한 믿음은 깊어져만 갔다.

그때 일련의 쾌락주의자들이 나타났다.
갱들이 그들의 문제 해결을 위해 패턴이란 기관총으로 클라이언트들에게 너희 문제는 이것이고 또한 이것이라야 한다 라고 윽박질렀던 것에 반하여, 클라이언트를 행복하게 해 주어야 문제가 해결된다고 믿는 그들은 클라이언트들이란 자신이 무엇을 원하는지 조차 모르므로 그들과 계속 대화하면서 그들이 진정으로 원하는 것을 알아차릴 때 까지 계속 입안의 혀 처럼 살살 굴러주다 보면 모두가 행복해지는 날이 오고 따라서 문제는 자연스럽게 해결된것과 같다고 주장했다.
모든 문제는 바로 클라이언트가 만족하지 않는다는 한 가지만 중요했던 것이다.
그렇다. 모두가 만족해하고 일정도 맞추고 돈도 챙겨서 떠나갈 수 있으니 흠잡을 곳 없이 좋다.
하지만 마음 깊숙히 왠지 이렇게 사는 것이, 다른 이의 욕망을 채워주는 것을 자신의 목적으로 사는 삶에 대한 왠지모를 불안감은 가시지 않는다.

프로그램이란 특정한 입력값을 받아 해당하는 동작을 하는 일련의 작업을 의미한다고 할 때, 프로그램을 만드는 프로그래머는 자신의 설계대로 자기손으로 만들어진 하나의 창조물이 자신의 의도대로 동작하는 것을 보며 만족감을 느낀다.
개발자 란 말을 들을 때 마다 무엇이 어떻게 되어야 한다 라는 목적에 대한 결정권을 다른 사람에게 맡기고 그저 부여받은 책무에 대해 처리하면 된다는 의기소침한 소시민의 이미지가 떠오른다.

회사를 옮기고 여러 종류의 회의에 참석하게 되면서 알게 모르게 개발자 란 언급을 직 간접적으로 받으며 내가 진정 원하는 것에 대해 한번 더 생각해보게 된다.

Posted by eoh

2009/09/20 18:38 2009/09/20 18:38
,
Response
No Trackback , No Comment
RSS :
http://endofhope.com/tc/rss/response/6

10만 펙토리얼

자주 방문하는 프로그래밍 관련 포럼에 글이 하나 올라온 적이 있다.
10만 펙토리얼 계산 속도
윈도우 계산기로 계산 결과를 올려 놓는 사람부터 함수형 언어로 계산해 본 결과까지 하나의 목적을 위해 서로 다른 접근을 볼 수 있어서 즐거운 글이었다.
나도 당연히? 프로그램을 짜서 돌려 보았는데, 해당 글타래엔 올리지 않았다.
java 로 뭔가 하면 뻑하면 flame 이 생기는 걸 보았던 터라 간만에 생긴 흥을 내가 나서서 깨어버리곤 싶지 않아서였다.

어제 메일이 왔는데, 서버 계정 만료일이 다가왔다고 알려주는 메일이었다.
뭐 몇푼 되진 않지만, 그렇다고 이용하지 않는 계정을 놀릴 필요도 없고 해서 블로그를 써야할 마음이 들었다.

첨부한 코드는 Java 로 10만 펙토리얼을 구하는 코드이다.
argument 없이 돌리면 thread 를 4개 생성하여 부분곱을 구하고 나중에 해당 부분곱들의 결과를 합하여 최종 값을 구해 낸다.
이 코드를 테스트할때 4개짜리 프로세서를 가진 기계에서 돌렸기 때문에 쓰레드를 3~4개가 가장 성능이 좋을 줄 알았는데, 쓰레드 숫자가 16개 까진 상당히 좋은 결과가 나와서 의외? 였다.
결과는
4개 이상이면 context switching 비용이 분명 들 텐데, 분명 인생의 오묘함도 이런 게 아닐까?

Posted by eoh

2009/08/31 21:40 2009/08/31 21:40
, ,
Response
No Trackback , No Comment
RSS :
http://endofhope.com/tc/rss/response/3


블로그 이미지

말할 수 있는 것은 분명하게 말해질 수 있다. 말해질 수 없는 것에 대해서는 침묵해야 한다. 논리 철학 논고 - 루드비히 비트겐슈타인.

- eoh

Archives

Authors

  1. eoh

Recent Comments

Recent Trackbacks

Calendar

«   2012/05   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Site Stats

Total hits:
20037
Today:
22
Yesterday:
47