Skip to main content

Blub 레벨 높이기

갑->을이라고 할 때: '갑'는 '을'보다 자신이 더 잘났다고 생각한다.
갑<->을 이라고 할 때: '갑'과 '을'은 둘 다 자신이 더 잘났다고 생각한다.

c0037181_04030621.gif
출처: 프로그래머 서열

.

Beating the Average라는 글에 보면 Blub Paradox라는 말이 있습니다. Blub Paradox를 이해하기 위해서는 먼저 프로그래밍 언어는 모두 가지고 있는 힘이 다르다는 사실을 인정해야 합니다. C언어가 기계어보다 더 강력하듯이 python이나 C++, ruby, java, lisp 등의 고급 언어들 사이에도 이런 서열이 존재한다는 것이죠.

그럼 이제 Blub이라는 가상의 언어를 생각하고 이 언어를 현재 우리가 사용하고 있는 언어라고 합시다. 이 언어가 COBOL보다는 강력한 언어라고 가정하면 서열은 다음과 같습니다.

기계어 < COBOL < Blub < ?


이제 Blub 프로그래머가 아래, 즉 COBOL과 같은 언어를 보면 COBOL이 왜 Blub보다 약한 언어인지를 알 수 있습니다. 자신이 사용하고 있는 Y라는 기능이 COBOL에는 없기 때문이죠. 심지어 어떻게 Y라는 기능도 없는 언어로 프로그래밍을 할 수 있는지 궁금해 합니다.

하지만 반대로 위를 올려다보면 우리는 우리가 보고 있는 것이 무엇인지를 깨닫지 못합니다. 단지 Blub으로도 할 수 있는 일을 이상한 문법이나 방법으로 하고 있다고 생각하기 쉽죠. 결국 그 언어가 왜 Blub보다 강한지 알지 못하는데 이를 Blub Paradox라고 합니다. 이렇게 더 강한 언어의 강력함을 이해하지 못하는 이유는 바로 우리가 현재 Blub의 높이에서만 생각할 수 있기 때문입니다.

위의 내용에서 유추해보면 결국 모든 언어의 장/단점과 차이를 이해하기 위해서는 가장 강력한 언어를 알아야 한다는 결론이 나옵니다. 물론 위에서 언급한 Paul Graham의 글에서는 이 언어가 Lisp이라고 이야기하고 있죠.

얼마전까지 제 Blub은 C++였습니다. 이전엔 python을 그저 C++의 인터프리터 버전으로 간주하고 사용했습니다. 즉, C++로도 할 수 있는 일만 python으로 했던 것이죠. 그런데 지난주에 테스트 자동화 툴을 python으로 작성하다가 실제 테스트 케이스를 작성할 사람들을 위해 자동으로 테스트 케이스가 등록되도록 python의 reflection 기능을 공부하여 사용하게 되었습니다. 이 기능을 사용하다 보니 이런 생각이 들더군요. "reflection 기능도 없는 C++에서 앞으로 이런 작업을 해야 하면 어떻게 하지?"

이를 계기로 제 Blub 레벨이 조금은 올라가지 않았나 생각합니다.

저도 C++이라는 언어에 대해서는 제법 잘 알고 있다고 생각하는데 Lisp이나 Smalltalk같은 언어를 아는 사람을 보면 괜시리 주눅이 들곤 합니다. 아마 저보다 높은 Blub 레벨을 가지고 있어 저보다 넓은 시야를 가지고 있을거라 생각하기 때문이었을 겁니다. 저도 Lisp의 경우엔 몇번 배우기를 시도해 보았는데 매번 더 재밌거나 더 급한 일들이 생겨 실패하곤 했습니다. 올해 다시 한번 Lisp이나 Smalltalk에 도전해서 Blub 레벨을 올려 봐야겠습니다.

그나저나 위의 그림을 보니 Java는 제대로 안습이군요. :-) Java가 제가 별로 좋아하는 언어가 아니라 다행입니다. 아니었다면 상처 받았을 듯.

Comments

  1. 전 template없이 어찌 코드를..

    이란 생각을 할때가 있다는.. 킁;

    ReplyDelete
  2. 저랑 Blub 레벨이 비슷하시군요. :-) template도 그렇지만 전 destructor가 없어서 RAII가 안되는 언어들을 만나면 대략 난감입니다. 보통 그런 언어들이 RAII 대신 사용하는 try~finally 블록은 어딘지 우아하지가 않아 보여요.

    ReplyDelete
  3. 그게.. 신기하게도 실제로 Java 프로그래머들은 이유없이 C#, C, C++ 등의 언어에 대해 열등감을 가진 것 처럼 보입니다.
    반면 Ruby 프로그래머들은 세상에 루비만 있는 줄 알죠.
    잘 작성된 표 같습니다. ㅎㅎ

    ReplyDelete
  4. 음.. 그리고 C++에는 비록 reflection이 없지만, template meta programming이라는 강력한 도구가 있잖아요...

    ReplyDelete
  5. 아마 Ruby 프로그래머들의 자존심은 자신들이 그래도 제일 Lisp의 후계자다라는 생각이 있어서 그런건 아닐까요? Java는 저번에도 한번 썼던 것 같은데 eclipse만 없었더라면 C/C++과 Python, Ruby같은 script 언어들 사이에 끼어서 고생하지 않았을까 싶네요. 언어 자체에 문제가 있다기보다는 언어로써의 위치에 문제가 있는 것 같습니다. 물론 언어 자체가 좀 재미가 없다는 사소한(?) 문제도 있긴 하죠. :-)

    그리고 C++의 template meta programming이 강력하긴 하지만 실제 현장의 프로그래머들이 작성하는 코드에서 얼마나 쓰이고 있는지는 의문입니다. 게다가 기능이 강력한 만큼 readability와 understandability가 떨어져 maintainability가 현저히 낮아지는 문제도 있습니다. 제가 속한 프로젝트에서 template이 쓰인 코드들은 전부 제가 만든 것들인데 이 코드를 본 사람들이 질문이라도 하면 어디서부터 설명해야 할지 막막할 때가 자주 있습니다. template -> template specialization까지만 이해시키려 해도 쉽지 않거든요. 암튼 template meta programming이 누구나 사용할 수 있는 유용한 개발 도구가 될지 아니면 라이브러리 제작자들이나 사용하는 도구가 될지는 좀 더 지켜봐야 할 것 같습니다.

    그리고 bloglines에 한동안 글이 없다 했는데 블로그가 접속이 안되네요. :-| 바쁘신가봐요. 얼른 다시 문 여시길 기다리고 있겠습니다. ;-)

    ReplyDelete

Post a Comment

Popular posts from this blog

1의 개수 세기 - 해답

벌써 어제 말한 내일이 되었는데 답을 주신 분이 아무도 없어서 좀 뻘쭘하네요. :-P 그리고 어제 문제에 O(1)이라고 적었는데 엄밀히 얘기하자면 O(log 10 n)이라고 적었어야 했네요. 죄송합니다. ... 문제를 잠시 생각해보면 1~n까지의 수들 중 1의 개수를 얻기 위해서는 해당 숫자 n의 각 자리의 1의 개수가 모두 몇개나 될지를 구해서 더하면 된다는 사실을 알 수 있습니다. 예를 들어 13이라는 수를 생각해 보면 1~13까지의 수에서 1의 자리에는 1이 모두 몇개나 되는지와 10의 자리에는 모두 몇개나 되는지를 구해 이 값을 더하면 됩니다. 먼저 1의 자리를 생각해 보면 1, 11의 두 개가 있으며 10의 자리의 경우, 10, 11, 12, 13의 네 개가 있습니다. 따라서 2+4=6이라는 값을 구할 수 있습니다. 이번엔 234라는 수에서 10의 자리를 예로 들어 살펴 보겠습니다. 1~234라는 수들 중 10의 자리에 1이 들어가는 수는 10, 11, ..., 19, 110, 111, ... 119, 210, 211, ..., 219들로 모두 30개가 있음을 알 수 있습니다. 이 규칙들을 보면 해당 자리수의 1의 개수를 구하는 공식을 만들 수 있습니다. 234의 10의 자리에 해당하는 1의 개수는 ((234/100)+1)*10이 됩니다. 여기서 +1은 해당 자리수의 수가 0이 아닌 경우에만 더해집니다. 예를 들어 204라면 ((204/100)+0)*10으로 30개가 아닌 20개가 됩니다. 이런 방식으로 234의 각 자리수의 1의 개수를 구하면 1의 자리에 해당하는 1의 개수는 ((234/10)+1)*1=24개가 되고 100의 자리에 해당하는 개수는 ((234/1000)+1)*100=100이 됩니다. 이들 세 수를 모두 합하면 24+30+100=154개가 됩니다. 한가지 추가로 생각해야 할 점은 제일 큰 자리의 수가 1인 경우 위의 공식이 아닌 다른 공식이 필요하다는 점입니다. 예를 들어 123에서 100의 자리에 해당하는 1의 개수는 ((123/1...

CodeHighlighter plugin test page.

This post is for testing CodeHighlighter plugin which uses GeSHi as a fontifier engine. ((Those code blocks are acquired from Google Code Search .)) ((For more supported languages, go CodeHighlighter plugin or GeSHi homepage.)) C++ (<pre lang="cpp" lineno="1">) class nsScannerBufferList { public: /** * Buffer objects are directly followed by a data segment. The start * of the data segment is determined by increment the |this| pointer * by 1 unit. */ class Buffer : public PRCList { public: Buffer() { ++index_; } PHP (<pre lang="php" lineno="4">) for ($i = 0; $i $value = ord( $utf8_string[ $i ] ); if ( $value < 128 ) { // ASCII $unicode .= chr($value); } else { if ( count( $values ) == 0 ) { $num_octets = ( $value } $values[] = $value; Lisp (<pre lang="lisp">) ;;; Assignment (define-caller-pattern setq ((:star var fo...

C++ of the Day #43 - SQLite3 C++ wrapper #1

The Definitive Guide to SQLite 를 읽다가 공부 겸 해서 C++ wrapper를 만들어 보았습니다. 최대한 C++ 냄새(?)가 나도록 만들어 보았습니다. :-) ((SQLite는 복잡한 관리가 필요없이 사용가능한, 파일이나 메모리 기반의, 라이브러리로 제공되는, 약 250kb 용량의, 대부분의 SQL92문을 지원하는, open source RDB입니다.)) 이 wrapper를 사용하기 위해서는 (당연하게도!) sqlite3 와 (당연하게도?) boost 라이브러리가 필요합니다. 사용 예들을 살펴보는 것으로 설명을 대신합니다. 이번 글에서는 다음과 같은 contacts 테이블이 test.db에 존재한다고 가정합니다. CREATE TABLE contacts ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, phone TEXT NOT NULL, UNIQUE(name, phone) ); Command 먼저 test.db 파일을 사용하기 위해 다음과 같이 파일 이름을 주어 connection 객체를 생성합니다. 생성과 동시에 test.db와 연결이 이루어집니다. ((생성자외에 open() 함수를 사용할 수도 있습니다.)) sqlite3pp::connection conn("test.db"); 다음은 contacts 테이블에 정보를 추가하는 가장 간단한 방법입니다. connection 클래스에서 제공하는 execute 함수를 사용합니다. ((executef 함수를 사용하면 printf와 같은 문법을 사용하여 query문을 작성할 수 있습니다.)) conn.execute("INSERT INTO contacts (name, phone) VALUES ('user', '1234')"); 위와 동일한 작업을 parameterized query를 사용하여 할 수도 있습니다. ((step()함수가 실제 query문을 수행하는 함수입니다. ...