태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'2011/09'에 해당되는 글 2건

  1. 2011.09.03 An introduction into SICP (6)
  2. 2011.09.03 가벼운 가방의 중요함 (5)

An introduction into SICP

Daily life/Hard study 2011.09.03 21:37
SICP는 Structure and Interpretation of Computer Programs 의 약자다. 마법사 책(wizard book)으로도 알려져 있으며, 한때(지금도?) MIT에서 1학년들에게 가르쳤다고 한다. 해커를 동경하거나, 이미 해커이거나, 해커가 되어가고 있는 사람들이라면 LISP의 한 방언인 Scheme의 존재는 알고 있을테고, scheme을 언급할 때 함께 튀어나올 수 밖에 없는 책으로 해커 문화와 뗄 수 없을 것 같... 다고 마음대로 생각한다.

유명세에 비해서 완독한 사람은 생각보다 많지 않은데, 책의 난이도가 - 혹은 읽는데 드는 잉여력이 - 꽤 높기 때문이다. 프로그래밍 스킬과는 별도로 체계적이고 논리적인 사고, 적절한 추상화 능력, 2차 이상의 Higher order 를 상상할 수 있는 능력 그리고 어느 정도의 하드웨어 지식을 요구한다. 거꾸로, 이 책에서 주려는 것이 저런 능력이기 때문에 잉여력만 충분하면 읽으며 깨달아가도 된다. 이런 경우까지 고려하여 이 책을 읽기 위한 최소한의 요구사항은 끈기Scheme 코드를 돌려볼 수 있는 환경이다.

책은 총 5개의 챕터로 구성되어 있으며, 각각

1. Building abstractions with procedures
2. Building abstractions with data
3. Modularity, Objects and State
4. Metalinguistic abstraction
5. Computing with register machines

이런 제목을 가지고 있다. 각 챕터에 대한 간략한 소개를 하자면,

1장:
 스킴의 기본적인 문법부터 시작한다. 프로시져-그러니까, 그냥 함수라고 하자-를 만들고 사용하는 연습을 주로 한다. 만들어진 프로시져 여러개를 조합해서 Compound procedure 를 만들면서 Building block을 쌓는게 이런거구나 느껴보게 된다. 그리고 장 말미에 Procedure 를 만드는 Procedure 를 만드는 Procedure ... 같은 Higher order procedure 의 맛을 좀 보게 된다.

2장:
 1장의 연결이라는 느낌이다. 1장에서 다룬 프로시져 사이를 넘나드는 "데이터"를 조명한다. 그리고, 프로시져와 데이터를 엮어 인터페이스의 생성 - 즉 추상화 배리어가 어떤 의미를 가지는지에 대해서 구구절절 설명하고 실습하게 된다. 그리고 Data-directed programming 이라는 짓을 하게 되는데, 이 부분은 Object-oriented 쪽의 정수와 맞닿아 있다. 거의 타입 시스템과 Message-passing 시스템을 직접 구현해 올리게 되는 (꽤) 놀라운 체험을 하게 된다.

3장:
 1, 2장까지의 Scheme 은 순수한 함수형 언어였다. 모든 프로시저는 referential transparency 를 가지고 있었다. 여기부턴 안그렇다. 시간에 따라 변화하는 상태가 등장하기 시작하며 머리가 조금 아파지기 시작한다. 기초적인 concurrency 에 대한 개념, 따라오는 문제, 이런 문제를 다루는 방법 등에 대해 맛을 볼 수 있다. (미친듯한 회로 시뮬레이션-_-) 그리고 3장 마지막에 나오는 stream - 사실 3장의 핵심은 이거다. Stream이 무엇인가? 어떻게 동작하는가? 에 대한 설명을 하며 다음 장에 본격적으로 등장할 Lazy evaluation 을 준비시킨다.

4장:
 책의 주제가 슬슬 드러나기(난이도가 급상승하기) 시작하는 곳이다. 책 표지에 왜 Apply-Eval 이 있을까? 에 대한 답이 시작된다. 우리는 스킴으로 스킴 코드를 실행시키는 인터프리터를 만들게 된다. 그 와중에 깨알같은 최적화들이 나오게 되고, 일반적인 인터프리터나 컴파일러가 이런 짓을 하겠구나 - 싶은 영감을 좀 얻을 수도 있다. 특히, Evaluator 를 만들고 여기에 Lazy-evaluation 을 적용시키는 작업을 직접 해보면, 꽤 많은 걸 느껴볼 수 있게 된다. 앞에서 주구장창 이야기했던 추상화의 소중함이랄까 ... 그리고, 뒤쪽 두 개의 소챕터는 amb로 설명되는 nondeterministic computing과, logic programming이 어떻게 구현될 수 있는지 맛보기를 보여준다. (STREAM!) 텍스트가 아이디어->구체화->코드, 의 과정을 설명하고 있는데 읽고 나면 간단해 보이지만, 책을 덮고 직접 그 길을 따라가 보면 이 책을 쓴 사람들이 얼마나 미친 내공의 소유자들인지 깨닫게 된다. ...

5장:
 4장에서 우리는 소프트웨어 세상의 끝을 보았다. 4장에서 코드를 실행시키는 코드를(Metacircular) 만들었으니까... 이제 한 단계 아래로 내려간다. Higher order이기 때문에 주의해서 읽어야 한다. 우리는 일반적인 가상의 기계어를 정의한 후에, 이 기계어를 시뮬레이션 하는 스킴 코드를 만들고, 이 기계어로 스킴 실행기를 만들어서, 기계어로 만들어진 스킴 실행기에 스킴 코드를 넣어 실행하는 시뮬레이션을 한다. 그리고 나서, 이번엔 실행기가 아니라 스킴 코드를 우리가 정의한 기계어로 컴파일하는 컴파일러를 만든다. 인터프리터와 컴파일러가 어떻게 다른지, 컴파일러가 만든 코드가 인터프리터에 비해 어떤 최적화를 더 할 수 있어서 빠른건지를 이해할 수 있게 된다. 연습문제들이 앞 3, 4 장에서 만들었던 유틸리티 코드를 많이 재사용하기 때문에 앞 장을 대강 읽었거나 문제를 하나도 안풀고 그냥 넘어왔다면 5장에서 능욕당하게 된다.
 
텍스트와 함께 많은 수의 연습문제들이 배치되어 있는데, 이 책을 제대로 읽은 사람들이 하나같이 "연습문제를 풀어보지 않으면 읽었다고 말할 수 없다"고 이야기한다는 점에 주목할 필요가 있다. 위에서 말한 완독이라는 표현은, 연습문제를 풀어보았다 - 라고 말할 정도를 뜻한다. 참고로 나는 모든 문제를 풀어본 상태는 아니고, 모든 문제에 대해 풀이를 시도해본 정도이다. 몇몇 난이도가 미친듯한(혹은 잉여력 스카우터를 폭발시킬듯한) 문제를 제외하고는 대부분 풀긴 했다. ... 사실 연습문제를 풀지 않으면, 끝까지 읽는게 불가능할지도 모르겠다. 이런 부분이 많지는 않지만, 앞쪽 연습문제에서 다룬 내용을 뒤쪽 텍스트에서 당연하다는 듯이 사용하고 있으니까.

나같은 경우에는, 연습문제를 풀면서 많이 배웠다. 진짜로, 많이. 원래 훌륭한 사람이라면 나만큼 많이 배울게 없을수도 있긴 하다. 어쨌거나 텍스트만 읽을 때 보다 연습문제까지 풀었을 때에 얻을 수 있는게 훠어어얼씬 많다는 것은 확실하다.

이 책을 읽을, 연습문제를 풀 사람들에게 줄 만한 조언은,

1. 1장, 2장은 뒤쪽을 위한 몸풀기다. 여기서 어려움을 느끼면 곤란하기 때문에, 책을 읽으며 순서대로 문제를 풀려는 생각은 버리고 책을 빠르게 여러번 읽으며 내용을 씹어먹으며 연습문제를 푸는게 좋을 것 같다.

2. 3장부터는 바로 실행해보기 귀찮거나 어려운 녀석들이 등장한다. 특히 stream 관련해서 텍스트에 있는 내용이나 연습문제를 돌려보기가 까다로운 경우가 있다. 일단, 스트림 관련 코드가 나오면 sicp 홈페이지에서 코드를 구하던가 아니면 문제는 스킵하고 텍스트에 있는 코드를 먼저 입력해서 "실행해볼 수 있는" 환경을 만든 후에 문제를 푸는게 좋다. 실행 환경을 먼저 만드는 것은, 이 후 책 끝까지 언제나 중요하다. 

3. 일단 풀어보거나, 혹은 구체적인 접근 방법을 떠올리기 전에 다른 사람의 풀이를 보지 않는다.

4. 삽질 기록을 어딘가(연습장이나 위키, 그 외 어디라도) 정리해 가기를 강추. 코드도 함께 남기면 나중에 앞 장의 코드나 풀이 기록이 필요할 때(4장부터는 앞쪽을 다시 읽어보게 되는 경우가 많다) 큰 도움이 된다. 나중에 앞을 다시 봤는데 기억이 안나고 기록도 없으면 책을 다시 읽고, 연습문제를 다시 풀어야 할지도 모른다.

5. 직접 만들어도 되고 있는 것을 써도 되는데, 테스트 코드 작성을 추천. 1, 2, 3장까지는 특히나 엄청나게 매우매우 유용하다. 나는 컴키드님 자작 테스트 툴을 썼는데 큰 도움이 되었다. 4장 이후로는 테스트가 곤란한 것들이 많아서 유명무실 ...

6. Pencil & Paper 를 항상 가까이에. 

특히 실행 환경 구성이 꽤 시간을 많이 잡아먹고, 우리를 지치게 하는 부분이다. SICP와 함께 자주 거론되는 책으로 HTDP(How To Design Programs)가 있는데, 이 책 저자들은 SICP를 타산지석 삼아서 - 실제로 SICP의 악명으로부터 HTDP가 나왔다고도 한다 - HTDP에서는 테스트해볼 수 있는 환경 구축에 신경을 매우 많이 썼다. 심지어 SICP 연습문제 풀이에도 MIT Scheme 보다 Dr.Racket(PLT Scheme) 이 더 나을 정도.

SICP를 씹어먹고 나면 CS, 혹은 프로그래밍 세계에서 자주 나오는 여러가지 개념들에 대해 보다 깊은 이해를 할 수 있게 된다. 왜냐, 거의 대부분의 주제를 (기초적인 수준이지만) from scratch 로 삽을 떠 보기 때문에 ...

몇 년째 SICP를 읽고 문제를 풀고 있다고 하면 재귀나, 고차함수 같은거 실제 필드에서는 쓸일 없는데 알아서 뭐하냐, 라는 태클이 간간히 들어오기도 했다. 여기에 대해 답을 하자면 재귀, 고차함수 이런게 실제로 프로덕션 코드에 쓰이는 일이 있는지 없는지 나야 잘 모르지만, 그게 중요한 게 아니다. 중요한 것은 생각의 도구/단위를 얻는 것이다. GOF 디자인 패턴 책에 설명된 패턴 중 상당수가, 함수가 1차 객체인 많은 언어들에서는 큰 의미가 없어진다. 언어의 패러다임을 이해하고 적절한 개념을 갖추고 있는 일반적인 개발자에게는 너무 당연한 스킬이라서. 자바에서 몇백 라인에 걸쳐 십수개의 클래스를 정의해가며 구현한 패턴들이 파이썬이나 루비, 루아 혹은 스킴에서는 단 몇 줄로(가끔은 One-liner)해결되는 경우가 꽤나 많다.

적절한 개념을 탑재하고 있으면, 적절한 개념이 지원되는 언어로 적절한 코드를 만들 수 있다. 그 개념이 자연스럽게 지원되지 않는 언어라면, 그 개념을 흉내내는 바탕을 깔(배운 용어를 써보자면, 추상화 단계를 만들) 수 있다. 이런 삽질들이 모여서 새 언어가 만들어지고, 기존 언어의 스펙이 확장되고, 여러가지 프레임웍들이 생겨나는 것이다.

문법을 알고 있는 아무 언어나 골라서, 이 언어로 쓰여진 규모 있는 오픈 소스 프로젝트의 저장소를 하나 받아와보자. 언어의 문법을 알고 있는 사람이라면 누구나 이 코드를 읽을 수 있다. 하지만 언어의 문법을 알아도 1년동안 이 프로젝트의 코드베이스를 이해하지 못하는 사람이 있는 반면, 몇 시간이면 대강의 구조를 파악하고 재미삼아 코드 수정까지 하는 사람이 있다. 코드 한 줄 한 줄이 모여 만들어내는 보다 큰 논리단위의 구성을 읽는 능력의 차이인데, 다른 말로 일반적으로 쓰이는 추상화 블럭들을 읽어내는 능력이다. 한 권의 책 치고, SICP가 커버하는 프로그래밍의 핵심 블럭들은 굉장히 넓은 범위에 분포되어 있으며, 아마 자주 쓰이는 대부분의 개념에 대해 맛을 볼 수 있으리라 생각한다.

SICP를 읽으면 뭘 할 수 있게 되요? 혹은 어떤 내공이 쌓여요? 라고 묻는다면, 간단하게 이렇게 대답하련다. 코드 말고 프로젝트 단위의 읽고 쓰기를 위한 내공을 조금 얻을 수 있다고. 물론, 이 책 말고 다른 곳에서도 얻을 수 있다. 얻어야 하는 것이 무엇이건 간에 도달하는 방법은 여러가지일 수 있다는게 이 책의 중요 포인트 아니던가.

'Daily life > Hard study' 카테고리의 다른 글

도깨비(tokebi) 더미 API  (5) 2012.07.12
2012/07/05: Hello world in xcode  (5) 2012.07.05
An introduction into SICP  (6) 2011.09.03
Reading: How To Design Programs(HTDP)  (0) 2011.07.13
D 프로그래밍 언어 - 오타(?)  (3) 2011.05.12
SICP study: 근황  (3) 2011.04.27
tags : SICP, 리뷰, 추상화
Trackbacks 1 : Comments 6

가벼운 가방의 중요함

Thoughts 2011.09.03 19:34
가벼운 마음으로 산책을 나갈 때에도 왜 이렇게 부질없는 것 들을 챙기게 되는지 모르겠다. 5분거리 집 앞 카페에 가서 가방을 열어보면 맥북, 책, 카메라, 물통, 노트, 선글라스, 기타등등 - 이런 것들이 들어있는데 대체 왜?

나갸야지 룰루랄라 하면서 가방을 챙길때, 별 생각 없이 있다가 정신을 차려보면 이렇게 되어 있다. 그리고 대부분의 경우 다시 집에 돌아올 때까지 가방에서 꺼내지조차 않는 물건이 대부분이다. 손에 쥐기는 쉽지만, 놓기는 어렵다. 버리거나 얻는 등 소유의 차원 이전에 쓰지 않을 물건을 괜히 들고가는 습관의 문제랄까.

물론 그렇게 챙긴 물건이 유용한 경우가 아예 없진 않겠지. 하지만 잘 생각해보면 유용하게 사용한 그 물건이 없었더라도 크게 곤란하진 않았을 것 같다. 이렇게 쓸데없는 물건을 하나둘씩 챙겨 다녀서 얻는 건 근거없는 심리적 안정감? 인가... 논리적으로 설명이 안된다.

내 가방이라는 일상 아이템 이야기이지만, 그 중심은 나니까 당연히 이런 경향은 나의 다른 쪽으로도 드러난다. 물리적으로 뿐 아니라 심리적으로도. 요즘 쓸데없는 걱정을 하면서 심리적 부담을 가지는 것 - 이라고 써놓고 보니 나 뿐 아니라 대단히 많은 사람이 그럴 것 같은데 ... - 도 비슷한 것 같고. 결국, 몸이든 마음이든 끊임없이 쓸데없는 공회전을 하며 내 영혼을 좀먹는다.

몸과 마음은, 어느 한 쪽을 끌더라도 다른 쪽이 따라가게 마련이다. 쉬운걸 먼저 해볼까. 가방을 가볍게 만들어 보자.

그럴려면 챙길 것을 잘 고르기보다는, 잠시 놓아 두어도 될 녀석을 공격적으로 골라낼 필요가 있다. 공격적으로.

'Thoughts' 카테고리의 다른 글

가벼운 가방의 중요함  (5) 2011.09.03
머리 스타일은 얼마나 중요한가?  (2) 2011.07.07
Mental stability  (1) 2011.07.02
엔터를 눌러라  (2) 2011.06.18
투표는,  (0) 2011.04.20
인지하는 세상의 범위로부터 시작한 갭모에(응?)  (1) 2010.09.19
Trackbacks 0 : Comments 5