2019년 10월 27일 일요일

[리뷰][맨먼스미신]을 읽고

이 책은 저자가 한 프로젝트를 진행하면서 겪었던 내용을 에세이로 적은 책이다.
이 책은 소프트웨어 개발자의 이야기라기보다 인간들의 이야기이다.
우리 인간들이 일을 함께 하면서 일어나는 일이다. 용어들만 바꾼다면 어떤 산업에서도 적용될 이야기이다.

이 책에서 그 유명한 대사가 나오는데 바로
여자 9명이 있다고 아기가 1개월만에 나오는 것이 아니다.

이 대사가 우리가 일을 할 때, 무엇을 생각하고 계획해야 하는지 알려주는 것이라 생각한다.

내용

이 책은 프로젝트를 어떻게 관리해야 하는지 설명한다. 그는 자신이 믿지는 않지만 개발자의 경력과 생산성에는 큰 차이가 없는 연구결과를 지속적으로 알려준다.(믿지않으면서 왜 지속적으로 보여주는 거지)
아마 우리가 생각하는 통념을 조금이나마 깨뜨리려고 하는 것이 아닌가.
나에게 가장 기억에 남는 것은 일반적으로 개발을 해서 앱을 만드는 것과 그 앱을 상용화하기 위한 제품으로 만드는 것에는 아주 큰 차이가 있다는 것이다.

생산성 측면에서 보면 적은 인원의 외과의(스타개발자)가 최고의 성능을 가져오면 버그율도 적다. 하지만 큰 프로젝트를 진행하려면 시간이 아주 오래 걸릴 것이다.
그래서 사람이 더 필요하게 되는데 사람이 더 많아질 수록 의사소통, 교육 등에 병목이나, 마찰율(책에는 없는 단어다 ㅋㅋ)같은 것이 발생하여 진행이 많이 떨어지게 된다는 점을 말한다.
하지만 상용제품은 그밖에도 다른 것들에 문제가 있는데, 바로 요구사항 적립의 체계화, 테스트, 문서화, 재무관리 등으로 실제 개발시간에 수배의 노력(책에서는 9배라고 나온 것으로 기억한다.)이 필요하다는 것이다.

외과 수술 팀이라는 형식으로 팀을 꾸릴 것을 제안한다. 외과의과 나머지라고 부를 수도 있겠다. 바로 집도하는 외과의를 필두로 그를 보조하는 사람들을 분야별로 나눠서 구성하는 것이다.
재무, 프로그래밍언어, 새로운 툴 등을 분야별로 나눠서 처리하여 외과의를 보조한다. 신선한 방식이다. 아직 개발을 하면서 이런 형태를 본 적이 없어서 어떨지는 잘 모르겠지만, 좋을 것 같긴한다.

그리고 뒷부분으로 갈수록 문서화에 대한 내용에 노력을 기울인다. 주목할만한 점 중에 하나는, 개발을 하는데 서로의 이슈나, 요구사항 변경내용을 모두 적어서 모든 담당자들이 보도록 해서 서로 무슨일을 하는지 공유하는 것이 중요하다고 했지만,
종단에는 시간이 지나서 자신이 틀렸다고 말한다. 서로가 무슨 일을 하는지 모르고 자신의 업무에 집중하며 연결되어야 하는 부분에만 집중하는 것이 더 효율적이라고 주장이 대두되었고, 그는 그에 동조한다.

또한 논란이 되었던 은 탄환은 없다는 소프으웨어 개발에 지름길이란 없다는 것을 서술한다.
소프트웨어가 복잡한 것은 그 내재된 성질이기에, 도구로 고칠 수 있는 것이 아니라는 것이다. 객체지향 언어나 다른 방법론들이 쏟아져 나오지만, 결국 복잡성은 밖에 문제가 아닌, 소프트웨어 개발 자체가 가진 성질이며, 그것들을 없애주는 은탄환은 없다고 말한다.

이 책은 개발보다는 소통에 관한 내용이 많다. 그래서 누구라도 읽어볼만 하다고 할 수 있다.

[리뷰][클린 아키텍처]를 읽고

클린 아키텍처는 밥 아저씨의 클린 시리즈에서 가장 최신작인 것 같다.
이 책은 이전에 읽었던 [클린코드]와는 달리 아주 멀리서 소프트웨어산업을 바라보고 자신의 생각을 담아내고 있다.

내용

초반에는 자신이 생각하는 소프트웨어에 대해 설명하며 무엇이 소프트웨어를 더욱 소프트하게 만드는지 알려준다.
소프트함이라는 것은 변하기 쉬워야 한다는 것이다. 변하기 어렵게 만들거였으면, 하드웨어로 만들었을 것이라는 것이 그의 주장이다.
극단적인 예로, 변하기 쉽지만 요구사항에 맞지 않는 프로그램과 요구사항에는 맞지만 변하기 어려운 프로그램을 주어지면 그는 주저없이 첫번째를 선택하겠다고 말한다.
변하기 쉬운 것은 요구사항에 맞출 수 있지만, 후자는 비즈니스 로직이 변하거나, 버그를 발견했을 때, 바꾸기 어려우므로 안된다는 것이다.
물론 전대 변할 수 없는 프로그램은 없다. 하지만 프로그램을 변화시켜서 기대되는 비용과 개발을 하는 비용의 수지타산이 맞지 않을 때, 변할 수 없는 프로그램이라 부를 수 있다면 그런 프로그램은 존재할 것이다.

중반부터는 어떻게 하면 안전한 코드를 만드는지 설명한다. 하지만 코딩자체를 말하지는 않는다. 오히려 컴포넌트나 서비스같은 단위로 설명한다. 하지만 이 모든 내용은 작게는 코드에 대한 내용과 별 다를 것이 없어보인다.
그는 객체지향에 대해 설명을 하지만, 객체지향에 어떤 것도 이전에 C로 코딩을 하던 개발자들을 더 나은 개발자로 만들지는 못했다는 것을 설명한다. 왜냐하면 당시 개발자들 모두 그렇게 개발을 했었기 때문이다.
상속, 캡슐화, 다형성 모두 C언어로 가능한 구현들이었다. 대부분 문법적으로 간단하게 해준 것이며, 그 마저도 어떤 것은 오히려 구현이 불안정하게 만들었다. 저자가 객체지향으로 넘어가면서 얻은 장점은 다형성이라고 주장한다.

그리고는 지속적으로 그래프를 보여주면서 컴포넌트의 의존성의 방향이 얼마나 중요한지 설명한다. 나는 처음 이런 것을 보면서, 저자의 깊이를 더 알게 되었고, 정말 나중에 한 번 더 읽어야 겠다는 생각을 했다.
더해서 DI라는 것이 어떻게 아키텍처에서 쓰이는지 알게 되었다. 아무때나 DI를 다 붙잉는 것이 아니라. 이 방향을 바꾸기 위해서 하는 것이라는 것을 알게 되었다.
더해서 컴포넌트를 분리할 때도 DI를 사용해서 A,B컴포넌트에 서로 로직들이 잘 분리되도록 하는 것이다.

확실히 저자는 다형성에 큰 의의를 두고 있었다.

또 기억나는 것은 바로 구현에 대한 결정은 나중으로 미루라이라는 것이다. 그는 지속적으로 플러그인 패턴을 강조했다. 예를들어, 출력되는 곳이 콘솔일지, 프린터일지, HTML일지 이런것은 나중에 결정하라는 것이다.
환경은 또 어떨까? 웹으로 할 것인지 아닌지도 나중에 결정할 수 있도록 해야한다. 영속성은? DB로 할지도 나중에 결정해야 한다. 단순히 오라클/MySQL/... 중에 뭘 고를지 정하는 것이 아니다.
처음에는 map자료구조에 메모리로 저장하여 개발함으로써 영속성의 결정을 미룬다. 그리고 파일로 저장해서 또 미룬다. 미루고 미룬 후에 결정하는 것이다. 저자는 때때로 DB를 사용하지 않고 파일로 저장하고 가져와서 로딩하는 방식을 사용했다.
왜냐하면 DB가 필요 없었기 때문이다. 파일로도 충분했다.

이 구현을 미루는 것은 아키텍처에게 유현함(soft)함을 가져오게 해주고, 이런 외부 사항들로과 비즈니스로직을 자연적으로 분리시켜주게 된다. 그는 software가 firmware가 되는 것을 싫어했다. 펌웨어는 한 하드웨어에 종속되어 움직이는 경우가 대부분인데
그의 관점에서는 특정 DB에 종속된 것, 아니면 DB에 종속된 것을 펌웨어라 간주한다. 왜냐하면 세상은 많이 복잡해졌고, 그 정도의 종속도 펌웨어라는 것이다.
HTTP에 종속된 것도 펌웨어이다. 그는 코어 로직이 어딘가에 종속되지 않기를 바란다.

예를 들어보면 아래와 같다.

Core <- DB-AccessObject -> DB
     <- Network-Object
여기서 화살표 방향은 해당 객체가 무엇을 사용하는지 알려준다. 왼쪽에 있는 Core컴포넌트는 아무것도 사용하지 않아야 한다. 그래야 플랫폼이 바뀌어도 사용할 수 있다. DB를 사용하기로 결정했어도 Core는 변경되지 않는다. 그런데 말이 되지 않는다. 만약 Network에서 요청이 오고 DB-AccessObject를 실행해야 하는데 어떻게 Core에서는 사용하지도 않는데 실행을 한다는 거지? 그 답은 아래 DI에 있다(!!) 아래처럼 화살표가 되어 있다고 해보자.
Core -> DB-AccessObject -> DB
     <- Network-Object
이렇게 구현하는 것이 자연스러울 것이다. 여기서 DI를 적용하면?!
Core -> I-Persistent(in Core Component) <- DB-AccessObject -> DB
     <- Network-Object
이렇게 I-Persistent를 이용하여 저장하고 조회하는 것이다. I-Persistent는 코어 컴포넌트 안에 있고, 영속성관리를 무엇으로 해도 상관이 없게 되었다.
이것이 DI의 힘이다. 나는 지금까지 재사용을 쓰기 위해서다. 구현이 바껴도 사용할 수 있어서 DI를 쓴다고 알고 있었다. 물론 맞는 말이긴 해도, 이정도의 깊이가 있는 사람이 동일한 말을 하는 사람과는 전혀 달랐다.
나는 이정도의 넓은 숲을 보면서 말하지는 않았다. 왜냐하면 이런 세상을 전혀 몰랐으니까...

방향을 바꿔서 컴포넌트의 분리를 꾀하고, 종단에는 코어를 (유연하게 하는 것)지키는 것.
일류 아키텍처의 속마음을 잠깐 들여다 볼 수 있는 순간이었다.
마지막으로 가면 갈수록 그는 이 DI를 더 강조하는 것처럼 보인다. 그리고 실제적인 예시들을 보여주면서 어떻게 해야 하는지 알려 준다. 사실 다 읽었지만, 완벽하게 이해했다고 생각되지는 않는다.

나에게 또한 많은 생각을 하게 한 내용은 바로 프레임워크다.
그는 프레임워크에 종속되면 안된다고 말한다. 물론 프레임워크 개발자는 당신이 종속되도록 요청한다. 아예 하나의 언어처럼 붙어살길 원한다. 하지만 당신은 그렇게 하면 안된다는 것이다.
당신은 프레임워크를 툴로 써야 하며, 언제든지 바꿀 준비가 되어있어야 한다. 도구로써 써야 한다. 마법과 같은 일을 할 수 있다고 계약하지 말라.
당신에게 분명 되돌아 온다. 프레임워크에 종속되어 펌웨어가 되지 말라고 한다.

예를들어 자바의 스프링프레임워크를 예를 들면, Autowired를 하지말라고 한다. 차라리 Main에 다가 종속성을 다 쓰라고 말한다. 당신이 사용하는 모든 클래스에 spring이 import되어 있다면
종속되어 있는 것이다. 어쩌면 플러그인 패턴을 사용하여 DI로 프레임워크를 분리해서 사용하는 것이 해답이 될 수도 있을 것 같다.

끝없이 소프트하게 하라, 그것이 소프트웨어 개발자가 해야 할 일인 것이다.

이 책은 분명 다시 읽어야겠다. 누군가가 개발자가 되었다면, 그리고 소프트웨어개발자라면, 언젠가는 읽어야 할 책이라고 소개하고 싶다.

2019년 10월 25일 금요일

[리뷰][let over lambda]를 읽고-1

이 책은 [on lisp]를 보다가 머리를 식힐 겸 구매한 책이다.
다들 [on lisp]를 먼저 보라고 추천을 했지만, 어느정도 [on lisp]로 쉬운부분(매크로 초반까지) 읽고 [let over lambda]로 가는 것이 더 좋지 않을까 라는 생각을 한다.
[on lisp]보다 쉽다고 개인적으로 생각한다. [on lisp]는 아직 끝내지도 못했다... 무서워서... (일단 [on lisp]는 예제 코드가 너무 무섭다. 너무 길고 하나하나 쓰면서 이해하는데 시간이 너무 든다. 하지만 분명 나중에 정복해야 하는 책임은 분명하다.)

이 글은 단순한 감상이며 나중에 좀 더 심도 있는 내용을 적어야 할 것같다.

줄거리

그나저나
왜 이름이 [let over lambda]인가?
이것은 리스프에서 아주 기본적으로 사용되는 패턴으로 let으로 lambda를 덮는 형태를 말한다.
;; common lisp
(let ((a 10))
  (+ a 1))
;= 11
그러므로 [let over lambda]를 클로저라는 이름을 리습세상의 언어를 이용하여 우아하게 표현한 것이다.
이 [let over lambda]가 중요한 이유는 pointer를 조작하는 또 다른 방식이 될 것이기 때문이다.
이 let에서 생성되는 포인터를 이용하여 리스프 세상에서는 더 멋지고 자유롭게 표현할 수 있는 여지를 가지게 된다.
이것은 특히 커먼리습에서 대두된다.

이 책은 단순히 클로저만을 소개하는 책이 아니다. 시작이다. 이 책은 매크로를 설명한다. 이 책은 매크로로 어디까지 할 수 있는지 조목조목 설명해준다.
특히 뒤로 갈 수록 그 난이도는 올라가지만, 더 흥미로움은 더욱 커진다.

가장 충격적인 것은 Name Capturing이다. 이름이 충돌하는 문제인데, 이것은 람다에서도 나오는 베타-리덕션을 하다가 동일한 이름을 쓰는 매개변수가 있는 경우 리덕션에 문제가 생기는 경우와 비슷하다.
람다 계산의 경우 알파-컨버젼을 이용하여 시퀀스를 뒤에 붙이는 경우와 비슷하다.

책에서는 (gensym)으로 컴파일러가 내부적으로 현재 사용하고 있는 이름들을 확인하고 그들과는 겹치지 않는 이름을 만들어서 충돌이 일어나지 않도록 하는 방법을 제시한다.
하여 아래 코드는 절대로 참이 나올 수 없다.
왜냐하면 이 코드를 확인 한 후에 겹치지 않도록 이름을 제시해줄 것이기 때문이다.
(equal (gensym) (gensym))

이 서적은 더 나아가서, Name Capturing을 일부러 만드는 방식을 제시한다.
마치 큰 파도가 밀려오면 키를 돌려 정면으로 돌파해야 하는 것처럼.
Name Capturing을 피하는 것이 아닌, 정면 돌파하여 더 우아한 언어로 만들어주는 것이다.
마치 원래 그 언어가 있었 던 것처럼...
나중에 다뤄야 겠다.

후기

[let over lambda]는 이전에 람다계산 관련 책에 이어서 이번해에 읽은 최고의 책 중에 하나로 선정하겠다.
이번해에도 꽤나 많은 책을 읽었는데
기억에 남는 책은 이 두 권이라니... 나의 선택능력은 꽝인 것 같다.

꼭 읽어야 하는 책이다. 이 책을 읽기 위해서 common lisp, scheme, clojure 같은 언어를 둘러 본다해도
시간이 아깝지 않을 것이다.

2019년 10월 2일 수요일

[리뷰] lambda calculus에 대해 알아보기

https://www.notion.so/tombox/Lambda-Calculus-aa7f35c6a6ec4ecb9288e2bd33493dc8
lambda calculus에 관하여 이 책을 일독하였으나 기억이 가물가물해져서
다시 읽으면서 Notion에 적어보고 있다.

다시 읽어도 새롭다. 엄청난 책임이 틀림없다. 그리고 시간이 나면 Combinator에 대한 책도 읽고자 한다.