SICP 끝낸 기념으로 첫글 올려봅니다.

SICP를 끝내고 인터넷 어딘가에 흔적을 남기고 싶은데 마땅한 곳이 없어서 여기에 올립니다. 개인 블로그 메모장에 쓰던 것을 그대로 가져와서 말투가 반말체라 죄송합니다.

어쩌다 SICP팔이를 하는 동아리 선배를 통해 SICP를 알게 되고 "해커와 화가"에 낚여 SICP를 하게 되었다. 3월에 처음 SICP에 대해 들었을 때 나와 관련 없는 책이라 생각하고 할 생각은 없었는데 지금 와서 보니 MIT OICW 6.001 강의를 10B 까지 듣고 SICP를 연습문제 몇 개 빼고 다 본 사람이 되었다. 강의는 학기 중 자기 전에 한 강씩 들었고 책은 방학이 시작한 지 31일동안 봐서 7/22일 글을 쓴 날짜 기준 오늘 SICP 공부를 마쳤다. 그런 의미로 후기를 남긴다.

깃허브 링크 : GitHub - MShrimp4/SICP_Problems: SICP하면서 푼 문제 중 코드 부분만

  • 솔직히 내가 이 책을 연습문제까지 풀면서 했다는 증거물 + 체크포인트로 남겨둔 것이라 남이 볼 것을 상정하지는 않았다.

MIT OICW 6.001 후기
SICP를 보겠다고 생각한 후 이 강의를 알게 되어 책 공부 이전에 보게 되었다. SICP 1판 기준의 강의이지만 돌이켜 보니 SICP 책 보는데도 어느 정도 도움이 되었으니 책 보기 이전에 보는 것도 추천한다. 강의 자체에 대해 소감을 남기자면, Sussman 과 Abelson이 직접 책 내용을 강의하는 것도 좋았고, 중요하지 않다고 생각하는 내용은 최대한 정리한 코드 (와 우리의 코딩노예 George) 덕분에 이해하기도 비교적 쉬웠다. 80년대 CG와 강의 시작때마다 나오는 음악이 마음에 들어 6강 이후로의 난이도를 극복하고 계속 볼 수 있었다. 이것 말고도 이 강의를 갓강의로 만들어 준것은 당시 수업을 받던 학생들이다. 대본이라도 짜온듯한 학생들의 눈치빠른 대답과, 교육용 애니메이션의 학생들도 안할 만한 바람직한 질문을 하는 것을 보면 저 수업에서 내가 저런 질문을 할 수 있었을까 하는 생각이 든다. 그리고 강의 중간에 나눠준 뱃지와 강의 중간에 실물로 보여준 LISP 인터프리터 칩을 보면 내가 저 강의를 직강으로 들었으면 얼마나 좋았을까 하고 생각하게 만든다. 그리고 마지막 강의 10B가 끝났을 때 끝에 보여주는 영상을 보며 SICP 시작할 때의 음악의 긴 버전을 들으니 마치 한 학기동안 들은 명강의가 끝났고 그리고 강의의 모든 사람들과 헤어진다는 느낌을 받으면서 몇시간 동안 그 여운으로 정신을 못 차렸다.

SICP 책 후기

신기한 책이었다. 아직도 내가 무엇을 본 것인지 모르겠다. 처음에는 서론에서 무슨 마법 부리는 책이라도 되는 듯이 설명해서 진짜 마법 느낌 나게 가르치기라도 하나 생각했다. 돌이켜 보니 서론만큼 읽기 힘든 부분이 없었기도 하다. 지금 와서 책을 쭉 넘겨보니 그 페이지에서 배운 것이 페이지 따라 넘어가니 이 책을 분명 내가 배운 것은 맞는데 과연 내가 무엇을 한 것인가에 대해서는 아직도 답을 내리지 못하겠다.

1단원에서는 Scheme이 무엇을 할 수 있는지 보여주면서 직접 조작해보게 해서 신기했다. ackermann이 특히 재밌었다. 예전부터 덧셈 -> 곱셈 -> 지수로 이어지는 곳에서 한 단계 더 나갈 수 있지 않을까 했는데 이 문제가 해답을 제공해줬다. 코드가 생각을 표현하는 수단이 맞긴 했다. 그리고 직접 손으로 따라가면서 이 함수들이 어떻게 변해가는지(iterative / recursive) 보니 함수가 이런 과정을 통해서 계산하는구나를 느끼게 해주었다. 이걸 배워서 어디 쓰는지는 별로 신경쓰이지 않았다.

2단원은 지금 펼쳐보니 어떻게 과정을 추상화하고 데이터를 추상화하는지 배웠던 건 확실한데, 지루해서 중간에 3단원으로 넘어갔다가 나중에 나머지를 했다. 뭘 하는 건지도 알겠고 개념도 재밌는데 정작 코딩하기 귀찮았다. 신나게 소설 설정 짜다가 정작 쓰려고 하니 귀찮을 때의 느낌과 비슷했다.

3단원에서는 순수한 람다였던 함수에게 상태를 추가하면서 1단원에서 하던 것과는 다른 방식으로 프로그램을 만지기 시작했다. Environment Model도 손으로 그려보면서 상태를 추가한 함수가 어떻게 작동하는지 이해를 시킨 후 이것을 이용해 전자 회로 시뮬레이터를 만들어서 재밌었고 어떻게 이런 식으로 프로그램이 구성 가능한지 신기했다. Stream이 나왔을 때는 러시아워를 하는 느낌이었다. 딱히 좋은 설명이 떠오르지 않는다. 이 말고도 상태에 관련해서 여러 가지를 배웠지만 글이 길어져서 생략한다.

소제목에서 비범함이 보였던 4단원에서는 언어를 만들고 수정하는 작업이 대부분이었는데, 솔직히 이 책에서 Scheme을 써야 했던 이유가 있다면 4,5단원이 아닐까 싶다. 책을 따라가면서 언어를 분석하고 실행하는 코드를 만들면서 3단원의 시뮬레이터에서 느낀 재미와 신기함, 그리고 복잡함을 단원 전체에서 몇배로 느꼈다. 연습 문제에서 요구하는 여러 확장 기능들을 인터프리터 내의 언어에 넣으면서 만들고 있는 언어가 기반 언어 Scheme에 가까워지는 것도 재미있었다. 그 뒤의 몇 챕터에서 인터프리터의 2가지 변형을 다루면서 그 사이의 미묘한 차이점과 특징도 다루게 했는데 정말 예상치 못한 행동도 보여서 어려웠다. 이 단원 전체를 통틀어 드는 느낌은 없지만 확실히 이런 곳을 구경시켜주는 책은 드물 것 같다.

대망의 5단원은 피보나치 전용 레지스터 머신을 만들게 하는 것으로 시작해, 유사 어셈블리와 레지스터 머신 시뮬레이터를 만들더니 연습 문제를 통해 시뮬레이터 분석용 코드를 만들게 했고, 시뮬레이터 위에 인터프리터를 얹으려고 유사 어셈블리로 인터프리터를 쓰더니 그것으로는 충분하지 않았는지 컴파일러까지 쓰더니 마지막에는 어셈 손코딩, 컴파일된 코드, 인터프리터 위의 코드를 비교했다. 이런 내용을 한 단원에 넣으려 했다니 대단할 뿐이다. 이러는 중간에 pair를 관리하는 간단한 가비지 콜렉션 방법을 말해주고 인터프리터/컴파일러 부분에서는 Tail Call Recursion과 Lexical Scope에서의 최적화도 이야기했다. 이 와중에 4단원처럼 다루는 내용마다 기능 확장을 요구하는데 분명 문제 푸는 중에 코드의 구조를 이해하라고 문제를 만들었을 것이다. 이 확장 중에는 4단원 코드를 수정하는 것도, 4단원 코드를 참고하는 것도 있다.

5단원 맨 마지막에는 인터프리터와 컴파일러를 연결해 인터프리터의 함수와 컴파일한 함수가 서로 실행될 수 있도록 한 다음 챕터 4의 그 인터프리터를 컴파일하게 하고 마지막 두 문제에서 결과적으로 C로 작성된 Scheme 인터프리터와 컴파일러를 요구한다. 흥미로웠으나 내일부터 5일동안 컴퓨터 앞에 앉을 일은 없기에 필자는 풀어보려다 말았다.

팁이라 하기는 부족하지만 시행착오를 겪으면서 깨달은 내용들을 모아보았다.

  • 연습 문제로 푼 코드는 무조건 보관하고 있을 것. 나중에 쓴다. (8queen도 3단원에서 재등장하는데 2단원 코드와 비교해봐도 된다.)

  • Interactive SICP를 사용하면 코드 채점 기능도 이용할 수 있어서 좋다. 코드 저장 기능은 없어보이니 코드는 다른 곳에 백업해두자.

  • 참, Interactive SICP 는 3단원 중간부터 미완성 상태이다. (개인적으로 쓰다 배신감 느꼈다.)

  • 2단원의 Picture Language는 Racket (구 plt-scheme)으로 하면 된다. 이것 말고도 SICP에 대한 지원이 좋으니 끝까지 Racket으로 해도 된다.

  • 쓰고 있는 Scheme 이 지원하면 format, hash-table, track을 써보자.

format은 문자열 포맷팅 함수이다. C의 %d %f %c 생각하면 된다. (무슨 타입이든 ~s 쓰면 되고 줄바꿈은 ~%)

hash-table은 말 그대로 해시 테이블이다. 2장에서 table 필요할 때, 4장/5장에서 테이블 필요할 때 (속도가 빠르니) 쓰고 본인이 만든 구현이 필요하면 3단원에서 만드는 테이블을 쓰자

track은 그 함수를 트래킹해준다. 호출된 변수나 호출하는 함수 등을 보여줘서 디버깅할 때 도움된다.

##4,5단원 팁

  • 4단원을 하지 않고 5단원을 하는 것은 불가능하다. 4단원 코드를 쓰는 것은 물론 4단원 코드를 수정하는 연습 문제도 있다.

  • 리습 계열이 아닌 다른 언어로 SICP를 하고 있었다면, 누군가 4,5단원을 그 언어에 맞춰 다시 쓰기를 바라거나 아니면 Scheme으로 하자. 이 단원은 Scheme에 기대는 기능을 아주 많이 사용한다. 예를 들자면 Scheme에서 리스트 구조에 맞춰 입력값을 받는 read 함수를 쓴다던가 파싱된 언어의 구조를 수정할 수 있는 함수(그냥 car cdr같은 리스트 관련 함수다.)를 쓴다던가 하는 방식으로 4,5단원에서 설명하려 하는 interpretation에만 집중하고 파싱이나 기타 주제에서 벗어나는 내용은 회피를 하고 있다. 참고로 SICP in python은 4,5단원 부분에 해당하는 내용이 짧게나마 있다.

  • 4,5단원에 나오는 코드 같이 몇 장에 대해 설명하는 코드는 인터넷 버전 SICP에서 구해서(링크) 작동 가능 상태로 만들고 그 다음 읽기 시작할 것. 연습문제가 가끔 전체 코드 기반으로 돌아가는 것을 상정한 것들이 있다.

  • 4,5단원 코드는 디버깅하기 힘들다. 딱히 해결 방법은 없다.

  • 4,5단원 코드를 수정하다 고치기 불가능한 상태가 되면 롤백할 수 있도록 책 버전 순정 코드를 가지고 있는 것이 좋다.

  • 당연하지만 내용 이해 못하면 연습문제 풀기 힘들다. 12단원에서는 그럴 일이 비교적 적지만 345단원처럼 코드가 길면 푸는 게 불가능해진다.

  • 책에서 자주 찾아보는 내용에는 포스트잇을 붙여놓자. 4,5단원에서는 위의 이유 때문에 앞뒤로 가면서 읽을 내용이 많다.

  • 5단원 마지막 두 문제를 하려면 C(또는 다른 로우 레벨한 언어)를 알고 있어야 한다. 물론 그 문제를 푼다는 전제 하에서. 필자는 일정 때문에 계획만 세워보고 실제로 만들지는 않았다.

9 Likes

우와 정리잘 하시네요. 그리고, 반갑읍니다.
571084274E6516002E

어제 졸면서 쓴 글이라 퇴고는 했어도 불안했는데 첫 글이라 수정할 기회도 없이 검수 절차로 들어갔더군요. 생각보다 괜찮아서 다행입니다.

반갑습니다.

와우 대단하세요!!

sicp 매번 시작만 몇 번씩이나 했는데 2단원 언저리, 3단원 언저리 하다가 지쳐서 포기했습니다.

완전한 포기는 아니고 언젠가는 반드시 끝낼 숙명의 과제로 남겨두고 있는데요.

이론공부보다는 현실적인 코딩이 더 필요한 상황이라 아직 손대지 못하고 있네요.

어쨌든 완주한 분을 만나기 쉽지 않았는데 정말 반가워요 ㅎㅎ

4, 5 단원에 대한 후기는 잘 보기 힘든데 이렇게 자세히 적어주셔서 감사합니다…

당장은 쓰임새를 알 수 없어도 앞으로 어떤 식으로든 도움이 되시겠지요 ^^

아무래도 대부분 3단원까지만 하는 경향이 있습니다. 저야 방학에 시간이 많아서 5단원까지 한 것 같습니다. 억지로 5주 안으로 끝내겠다고 스케쥴을 진행해서 의지가 바닥나기 전에 한 것도 있지만요.

와 그래도 5주만에 끝내신건 대단히 빠른거 같은데요?

처음 방학 시작할 때 SICP를 한 주에 한 단원씩 해서 5주 정도만에 끝내겠다고 생각했는데, 시간이 널널한 줄 알고 첫 한두 주는 조금 풀다 놀았습니다. 지금도 후회되는군요. 그 여파로 마지막 2주는 늦게 자면서까지 머리를 혹사시키니 죽을 맛이었습니다. 그 와중에 아버지와의 약속 때문에 매일 2시 반에 집을 나서 수영 강습을 가서 1시간 정도 수영하고 5시에 집에 왔습니다. 덕분에 SICP와 수영을 같이 배웠군요. 공부 일수가 계획대로 5주였으면 그나마 나았을 텐데 일정으로 인해 5번째 주에는 컴퓨터 앞에 앉을 수 없는 상황이 되어 공부할 시간이 31일로 줄어버렸죠. 그래서 어쩔 수 없이 5단원 마지막 두 문제는 버리고 끝냈습니다.

SICP 4,5단원 연습문제를 하면서 스트레스를 받고 있는 저에게 며칠에 한번은 아버지께서 "그거 나머지는 KTX 안에서 읽으면 되지 않냐"는 말을 했는데 (자체검열)

하하 대단하세요 ㅋㅋ 방학을 완전히 올인하셨네요.

참고해서 저도 나중에 계획 한번 세워봐야겠습니다 ㅎㅎ