클로져 소개 강의 (한국정보통신산업노동조합)

82
클로져 소개 강의 한국정보통신산업노동조합 기술위원회 1 . 클로져인가? (45) 2 . 클로져 프로그래밍 (412)

Transcript of 클로져 소개 강의 (한국정보통신산업노동조합)

Page 1: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져 소개 강의

한국정보통신산업노동조합 기술위원회

1 부. 왜 클로져인가? (4월 5일)2 부. 클로져 웹 프로그래밍 (4월 12일)

Page 2: 클로져 소개 강의 (한국정보통신산업노동조합)

1부. 왜 클로져인가?

강의 순서

1. 요즘 함수형 언어가 주목받는 이유2. 함수형 언어란 무엇인가?3. 클로져는 어떤 언어인가?4. 클로져로 만들어 보는 생명 게임.

한국정보통신산업노동조합 기술위원회

Page 3: 클로져 소개 강의 (한국정보통신산업노동조합)

1부. 왜 클로져인가?

1. 요즘 함수형 언어가 주목받는 이유2. 함수형 언어란 무엇인가?3. 클로져는 어떤 언어인가?4. 클로져로 만들어 보는 생명 게임.

한국정보통신산업노동조합 기술위원회

Page 4: 클로져 소개 강의 (한국정보통신산업노동조합)

최근 언어는 함수형 프로그래밍이 대세

● JSR 335 : Java 8○ Lambda Expressions for the Java

● C++11 ISO 승인○ Lambda expressions and closures for C++○ Boost.Lambda

● C#○ LINQ

● F#● JavaScript

○ Closure and Lambda● Ruby● data-p

한국정보통신산업노동조합 기술위원회

Page 5: 클로져 소개 강의 (한국정보통신산업노동조합)

왜 그렇지?

한국정보통신산업노동조합 기술위원회

Page 6: 클로져 소개 강의 (한국정보통신산업노동조합)

컴퓨팅 환경의 변화1. 무어의 법칙컴퓨터의 성능은 18개월마다 2배씩 증가.

2. 무어의 법칙은 지금도 여전히... 그러나3. 기존에는 코어의 클럭 속도 증가는 물리적 한계에 봉착- 수냉식 냉각이 필요할 정도의 열 발생

4. 한 칩에 여러 개의 코어를 집적하는 방식으로 성능 향상이 이루어지는 멀티코어의 시대에 진입.

한국정보통신산업노동조합 기술위원회

Page 7: 클로져 소개 강의 (한국정보통신산업노동조합)

멀티코어 프로세서의 진화DualCore

QuadCore

HexaCore

16Core

OctaCore

한국정보통신산업노동조합 기술위원회

Page 8: 클로져 소개 강의 (한국정보통신산업노동조합)

멀티스레딩 프로그래밍이 필요해!

● 멀티코어 이전까지는 프로세서의 성능을 얻기위해 소프트웨어가 따로 할 일이 없다.

● 그러나 멀티코어 프로세서의 성능 이점을 얻기 위해서는 멀티스레딩 프로그래밍 필요.

● "공짜 점심은 끝났다" ○ Herb Sutter

● 이러한 하드웨어 산업계의 변화는 소프트웨어 산업에 멀티스레딩 프로그래밍이라는 진화압으로 작용

한국정보통신산업노동조합 기술위원회

Page 9: 클로져 소개 강의 (한국정보통신산업노동조합)

● 하지만 멀티스레딩 프로그래밍은 어렵다.● Tim Sweeney : Unreal Game Engene 제작

○ “C++ 언어로 멀티스레딩을 지원하는 것은 어셈블리 언어로 객체지향 소프트웨어를 작성하는 것 만큼이나 부자연스럽다.”

한국정보통신산업노동조합 기술위원회

멀티스레딩 프로그래밍은 어려워!

Page 10: 클로져 소개 강의 (한국정보통신산업노동조합)

왜 그렇지?

한국정보통신산업노동조합 기술위원회

Page 11: 클로져 소개 강의 (한국정보통신산업노동조합)

스레드는 구성가능하지 않다!

한국정보통신산업노동조합 기술위원회

● 구성가능성 (Composability)○ 1 + 2 = 3

● 모듈화 Modularity○ (1+2) + (3+4) = 10

● 레고 블럭처럼○ 작은 것을 모아서 큰 것을 만들어 내는 것!

● 참조하는 변수가 변하는 한...

Page 12: 클로져 소개 강의 (한국정보통신산업노동조합)

함수형 프로그래밍은 멀티스레딩에 강하다

● 스레드가 다루는 데이타가 불변이고 사용하는 함수가 순수하다면, 스레드가 아무리 많아도 문제가되지 않음.

한국정보통신산업노동조합 기술위원회

스레드 1스레드 2

데이타

Page 13: 클로져 소개 강의 (한국정보통신산업노동조합)

1부. 왜 클로져인가?

1. 요즘 함수형 언어가 주목받는 이유2. 함수형 언어란 무엇인가?3. 클로져는 어떤 언어인가?4. 클로져로 만들어 보는 생명 게임.

한국정보통신산업노동조합 기술위원회

Page 14: 클로져 소개 강의 (한국정보통신산업노동조합)

함수형 프로그래밍 특징 (1)

● 1급 함수 : 컴퓨터 과학자 Christopher Strachey가 만든 조어● 프로그래밍 언어에서 1급 시민의 지위란?

○ 런타임에도 생성되며, 함수의 인자로 전달되고 함수의 결과로서 리턴되며, 변수에 할당되는 것

○ 절차형/객체지향에서의 데이타, 오브젝트만의 지위○ 함수는 중세의 농노처럼 자유롭지 못한 속박 상태

● 함수형 언어에서 함수는 1급 시민 : 신분제의 철폐○ congratulation! first-class function! ○ congratulation! function as data○ congratulation! code as data

● 왜 이것이 중요한가?○ 함수도 데이타처럼 구성가능해짐(Composability)○ 고계함수, Closure, Partial application, Currying

한국정보통신산업노동조합 기술위원회

Page 15: 클로져 소개 강의 (한국정보통신산업노동조합)

함수형 프로그래밍 특징 (2)

● 순수 함수○ 참조투명성 : 같은 입력에 대해 항상 같은 출력을 낸다. 함수의 결과는 오직 입력된 파라미터에만 의존하며, 함수 외부의 어떤 값에도 의존하지 않는다. (전역변수에 의존하거나, 파일이나 네트웍으로부터 읽지 않는다.)

○ No Side effect : 함수의 실행이 부수 효과를 내지 않는다. 즉 프로그램의 어떠한 상태도 변경하지 않는다. (함수 외부의 변수를 변경하거나, 파일이나 네트웍으로 데이타를 내보내지 않는다. 예외(Exception)도 부수 효과이다.)

○ 수학 함수 : sin(x), cos(x), f(x) 등

한국정보통신산업노동조합 기술위원회

Page 16: 클로져 소개 강의 (한국정보통신산업노동조합)

함수형 프로그래밍 특징 (3)

● 불변 데이타● 이점

○ 스레드 안전 : "불변 객체는 항상 스레드에 안전하다" - Brian Goetz, Java Concurrency in JAVA

○ 부수효과 제거 : 순수함수 가능해짐.○ 쉬운 테스트 : 변화가 적으면 테스트도 적어진다.

● 불변 데이타는 다른 언어에서도 권장된다.○ Effective Java, Joshua Bloch

■ “클래스는 변화해야 할 분명한 이유가 없다면, 변경 불가능해야 한다. 만약 클래스가 불변일 수 없다면, 그 변경 가능성을 제한해야 한다.”

○ Effective C++, Scott Meyers■ Item3: Use const whenever possible.

한국정보통신산업노동조합 기술위원회

Page 17: 클로져 소개 강의 (한국정보통신산업노동조합)

최초의 함수형 언어, 리스프

● 1901 : 러셀의 역설(거짓말쟁이의 역설) - 수학의 붕괴?● 1928 : 힐버트 , "수학에서 모순을 몰아내라!"● 1931 : 괴델, 불완전성의 정리, "이런! 스승님, 불가능함을 수학적으로 증명해버렸어요!"

● 1936 : 튜링, "튜링 머신으로 불가능 증명"● 1936 : 처치, "람다 대수로 불가능 증명"● 튜링 머신과 람다 대수는 둘 다 계산 프로지져, 즉 계산의 자동화

● 처치-튜링 명제 : "튜링머신과 람다대수는 같다."● 1958 : 람다대수 기반으로 리스프 탄생, 존 매카시● 컴퓨터 과학에서 튜링머신은 하드웨어, 람다대수는 언어에 영향을 주었다.

한국정보통신산업노동조합 기술위원회

Page 18: 클로져 소개 강의 (한국정보통신산업노동조합)

리스프의 S-Expression

● 함수와 데이타가 같이 표현되어야...● 등도성(Homoiconicity)

○ 코드와 데이타를 같이 표현한다.● 재귀성 : 구성가능성을 만들어 낸다.● s-expression 혹은 sexpr

○ symbolic exression 준말○ 아톰 : 문자, 숫자, 기호○ 문구 (x . y) : x와 y는 sexpr

● 예○ (a . b) => (a b) : cons cell = car(a) . cdr(b)○ (x . (y . (z . NIL))) => (x y z) ○ (((S) (NP YP)) ((YP) (V))

한국정보통신산업노동조합 기술위원회

리스프 창시자 존 매카시

Page 19: 클로져 소개 강의 (한국정보통신산업노동조합)

객체지향의 문제점

● 객체는 구성가능하지 않더라.○ 변경이 의존관계를 타고 전파된다.

● 인간의 사고는 객체로 되어 있지 않더라.○ 객체보다 값(Value)이 더 단순하고 근본적임○ 1이 객체?, Motion이 객체?, 이름이 객체?○ 지금까지 객체로 사고하게끔 강요당함.

● 객체지향은 명사의 왕국○ 함수형은 동사의 왕국

● 패턴은 질병● 폴 그레함

○ "코드는 오로지 문제만을 표현해야지, 코드에 어떤 규정성을 둔다는 것은 뭔가 서투른 추상성을 사용하고 있다는 신호로 여긴다"

한국정보통신산업노동조합 기술위원회

Page 20: 클로져 소개 강의 (한국정보통신산업노동조합)

객체지향의 장점

● 다형성 : 함수나 메소드가 객체의 타입에 따라 다르게 행동

● 다형성은 OOP의 전유물이 아니다.○ 유닉스 파일 디스크립터는 다형성의 고전○ file, device driver, socket, pipe 등이 open/read/write/close 동작

● 캡슐화 ○ 구현을 인터페이스에 숨기는 것. ○ 그러나 객체는 상태를 지니기 때문에 완전한 캡슐화 불가능○ 입력과 추력만을 다루는 함수는 그 자체로 블랙 박스가 될 수 있기 때문에 오히려 더 강력한 캡슐화 가능

● 모듈화

○ 자바의 클래스와 패키지가 하는 모듈화

한국정보통신산업노동조합 기술위원회

Page 21: 클로져 소개 강의 (한국정보통신산업노동조합)

프로그램의 구조

한국정보통신산업노동조합 기술위원회

절차형 프로그램의 구조

● 개개의 코드가 프로그램의 상태를 바꾼다.

● 한 코드가 상태를 프로그램의 상태를 바꾸면 프로그램 전체 코드가 영향을 받는다.

함수형 프로그램의 구조

● 함수들을 유기적으로 조립하여 구성

● 함수는 인자에 따른 결과만 리턴

● 외부와의 인터페이스는 최상위 함수만 담당

Page 22: 클로져 소개 강의 (한국정보통신산업노동조합)

함수형 언어들

● Haskell

● Erlang

● ML

● CommonLisp

● Scheme

● Clean

● Clojure

● Scala

● Mathmatica

● XSLT

한국정보통신산업노동조합 기술위원회

Page 23: 클로져 소개 강의 (한국정보통신산업노동조합)

이중에서

왜 클로져인가?

한국정보통신산업노동조합 기술위원회

Page 24: 클로져 소개 강의 (한국정보통신산업노동조합)

최후의 언어

최후의 언어가 필요하다.● 이제 거의 발명할 수 있는 언어는 다 발명되었음 .● 새로운 언어는 기존 언어를 약간 수정한 수준.● IT분야가 현재의 기예의 단계에서 과학의 단계로 올라서야.● 수학이나 화학에서처럼 단일한 언어가 필요하다.

최후의 언어의 조건● 한 회사의 통제하에 있어서는 않된다.● 가비지 컬렉션을 지원해야 한다.● GOTO문이 없어야 한다.● 할당문 사용이 제한되어야 한다.(보다 함수적으로 되야)● 다형성을 제공해야 한다.● 멀티패러다임이지 않아야 한다.● 가상 머신상에서 실행되어야 한다.● 기존 프레임워크를 사용할 수 있어야 한다.● 빨라야 한다.● 단순한 문법이어야 한다.● 등도성(Homoiconicity)을 가져야 한다.

한국정보통신산업노동조합 기술위원회

로버트 씨 마틴 (일명 밥아저씨)40년 경력. Agile. XP. 소프트웨어 장인 운동. [소프트웨어 개발의 지혜], [클린 코드]

The Last Programming Language블로그 참조

Page 25: 클로져 소개 강의 (한국정보통신산업노동조합)

최후의 언어는 클로져

클로져의 특징● 클로져는 현대적인 리스프이다 . 리스프처럼 문법이 간결.

(F#이나 Scala는 C++처럼 문법이 복잡하고 기이하다)● 클로져는 JVM상에서 실행된다: 브라우져(ClojureScript),

CRL(Clojure.net)에서도 실행된다.● 클로져는 STM을 제공한다: STM은 동시성에 대한 최신 솔루션이다(Thread와 Lock이 필요없다).

● 클로져는 빠르다: 메모리 공유 불변 데이타 구조.● 다양한 지원: 튜토리얼, 블로그 IDE, 커뮤니티, 메일링리스트 .

한국정보통신산업노동조합 기술위원회

로버트 씨 마틴 (일명 밥아저씨)40년 경력. Agile. XP 소프트웨어 장인 운동. [소프트웨어 개발의 지혜], [클린 코드]

Why Clojure? 블로그 참조

# 클로져에 대한 웅변

“우리는 지금까지 수십년에 걸쳐 프로시져 (Procedure 절차형)에서 객체로 이전해 왔다. 이제 하드웨어의 물리적 제약이 비슷한 식으로 함수형 언어로의 패러다임 이동으로 우리를 내몰고 있다. 다음 몇 년 동안 우리는 어느 함수형 언어가 가장 좋은지 판별할 수 있는 다양한 프로젝트 실험들을 보게 될 것이다. 그 실험의 결과가 나올 때 나는 클로져가 매우 높은 위치를 차지할 것이라는 것을 완전 기대한다.”

Page 26: 클로져 소개 강의 (한국정보통신산업노동조합)

● 프로그래밍 세계에서 한 언어만 남는 것이 과연 좋기만 한 것인지...

● 여러 언어가 있어도 과학의 단계로 진입가능할 수도...● 프로그래밍이 어떤 의미에서 과학이 될 수는 있는 것인지도 불분명

● "과학이란 전문가 의견의 신뢰성에 대한 조직화된 회의주의다." - 리차드 파인만

● 마틴 파울러는 자바스크립트가 최후의 언어가 될 것이라고 농담.

● 다만 클로져가 최후의 언어로서 언급되고 있다는 사실 자체만 인정하자.

믿거나 말거나...

Page 27: 클로져 소개 강의 (한국정보통신산업노동조합)

1부. 왜 클로져인가?

1. 요즘 함수형 언어가 주목받는 이유2. 함수형 언어란 무엇인가?3. 클로져는 어떤 언어인가?4. 클로져로 만들어 보는 생명 게임.

한국정보통신산업노동조합 기술위원회

Page 28: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져의 특징● 2007년, 리치히키(Rich Hickey) 창제. 현재 v1.5● 현대적 리스프(Morden Lisp)

○ 함수형 언어○ Code As Data○ S-Expression○ 강력한 매크로

● JVM상에서 실행. 기존 자바의 모든 라이브러리 바로 사용가능닷넷용 Clojure.net, 브라우져용 ClojureScript도 있다.

● 최상의 STM(Software Transaction Memory): 동시성 처리 기술을 언어차원에서 제공. 스레드와 락 불필요. 자바의 가비지 컬렉터가 C의 포인터를 없앤듯이, 클로져의 STM은 스레드 제거.

● 단순성을 최대한 추구 : 기존 언어의 우연적 복잡성이 없으며, 또한 본질적 복잡성의 완화까지 시도.

● 동적 언어● 강력하고 유연한 동적 개발 환경 REPL 제공● 불변 존속성 데이타 구조 제공● 멀티메소드 : 다형성 제공

한국정보통신산업노동조합 기술위원회

클로져 창시자 리치 히키

Page 29: 클로져 소개 강의 (한국정보통신산업노동조합)

복잡성

● 어떤 언어가 더 우수하다고 말할 수 있는 근거는 무엇일까?● 소프트웨어의 본질적 복잡성과 우연적 복잡성

○ 본질적 복잡성 : 소프트웨어가 풀고자하는 문제 자체의 복잡성. 제거 불가능.

○ 우연적 복잡성 : 문제를 푸는데 사용되는 방법과 도구 에서 기인하는 복잡성. 제거 가능

● 고수준 언어일수록 우연적 복잡성을 제거한다.● 우연적 복잡성을 알아내는 법

○ 도메인 전문가와 작업하기.○ 비전문가에게 설명하기.

● 수학자와 수학 알고리즘 만드는데...○ 프로그래머 : "아 이부분에서는 포인터를 써야겠네요"○ 수학자 : "포인터요? 그게 뭐죠?"

● 아이에게 게임 만드는 것에 대해 설명하기○ 프로그래머 : "재네들은 스레드를 따로 돌려서 하는 거지"○ 아이 : "스레드요? 그게 뭐에요? 아빠."

● 클로져는 단순성을 최대한 추구 : 기존 언어의 우연적 복잡성이 없으며, 또한 본질적 복잡성의 완화까지 시도.

한국정보통신산업노동조합 기술위원회

프레디 브룩스"은총알은 없다"

Page 30: 클로져 소개 강의 (한국정보통신산업노동조합)

어떻게?

한국정보통신산업노동조합 기술위원회

Page 31: 클로져 소개 강의 (한국정보통신산업노동조합)

생각하는 방식을 바꾸면 된다● 우리가 생각하는 방식 자체에도 복잡성이 있다.● 우리가 생각하는 방식을 바꾸면 세상은 더 단순하게 이해될 수 있다.● 예 : 천동설과 지동설

○ 천동설과 지동설은 똑같이 행성들의 운동을 설명한다.○ 다만 지동설이 더 단순하다.

● 천동설○ 지구와 태양 이외의 다른 모든 행성은 부전원을 돌아야 한다.

● 지동설○ 모든 행성이 태양을 중심으로 공전만 한다. 달만 지구를 공전.

한국정보통신산업노동조합 기술위원회

천동설 지동설

Page 32: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져는 우리가 생각하는 방식을 어떻게 바꾸는가?

한국정보통신산업노동조합 기술위원회

Page 33: 클로져 소개 강의 (한국정보통신산업노동조합)

변화란 무엇인가?

객체지향에서의 변화● 객체 시스템은 세계를 지나치게 단순화시킨 모델

● 객체 모델에서는 시간 개념이 없다.○ 장소 기반으로 메모리가 변한다.○ 변화를 직접 인지 가능할 것으로 오해○ 각 시점에서의 데이타를 연결하지 못한다.

한국정보통신산업노동조합 기술위원회

클로져 창시자 리치 히키

[Are We There Yet?] 참조

Page 34: 클로져 소개 강의 (한국정보통신산업노동조합)

변화란 무엇인가?

클로져에서의 변화● 실개체는 원자적 불변값이다.

● 미래는 과거의 함수이다! 미래가 과거를 바꾸지 않는다.○ 과정은 과거로부터 미래를 창출한다.

● 동일자(Identity)는 우연히 관계된 값들의 계열이다.○ 단지 심리학적 인공물○ 변화를 견뎌내는 어떤 실개체가 아니다.

● 시간은 과정의 사건의 원자적이고 연대기적 연속이다.

한국정보통신산업노동조합 기술위원회

클로져 창시자 리치 히키

[Are We There Yet?] 참조

"연속의 생성은 있지만, 생성의 연속은 없다" - A.N. 화이트헤드("There is a becoming of continuity, but no continiuty of becoming" - A.N. WhiteHead )

Page 35: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

Page 36: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져의 불변 존속적 데이타 구조(Immutable Persistent Data Structure)

한국정보통신산업노동조합 기술위원회

Page 37: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져의 불변 존속적 데이타 구조(Immutable Persistent Data Structure)

한국정보통신산업노동조합 기술위원회

● 데이타 구조들○ 리스트, 벡터, 집합,맵

● 삭제는 없고 생성만 있지만 빠르다!● 변화를 다루는 것이 가능해졌다.● 변화를 다루는 4가지 동일자(Identity) 제공

○ Ref, Atom, Agent, Var○ 이들은 클로져에서 변화를 관리하는 레퍼런스○ 이 변화에 대한 동기적 접근을 위해 STM 제공○ 결국 멀티스레딩에 강하다.

● Storm : 클로져로 만든 실시간 분산 데이타 처리 플랫폼에서 적극 이용됨. (하둡의 배치 방식과 대조)

Page 38: 클로져 소개 강의 (한국정보통신산업노동조합)

10개의 자료구조당 10개의 함수보다 100개의 함수가 있는 한 개의 자료구조가 더 낫다. - Alan J. Perils, SICP 서문에서

한국정보통신산업노동조합 기술위원회

클로져의 데이타 구조의 시퀀스 추상

Page 39: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

데이타구조가 왜 중요한가?

● 데이타를 어떻게 구조화하고 모델링할 것인가가 코드의 모양새를 결정한다.

● 프레드릭 브룩스○ "당신이 나에게 플로챠트를 보이고 테이블을 숨긴다면, 나는 여전히 미심쩍어 할 것이다."

○ "당신이 테이블을 보여준다면, 플로챠트는 필요없다. 그것은 명백할 것이다.

● 에릭 레이몬드○ "당신이 나에게 코드를 보이고 데이타 구조를 숨긴다면, 나는 여전히 미심쩍어 할 것이다."

○ 당신이 데이타구조를 보여준다면, 코드는 필요없다. 그것은 명백할 것이다.

● 만약 데이타를 배열이나 오브젝트나 임의적인 맵을 모델링한다면 좋은 함수형 클로져 코드 작성은 불가능하다.

Page 40: 클로져 소개 강의 (한국정보통신산업노동조합)

1부. 왜 클로져인가?

1. 요즘 함수형 언어가 주목받는 이유2. 함수형 언어란 무엇인가?3. 클로져는 어떤 언어인가?4. 클로져로 만들어 보는 생명 게임.

한국정보통신산업노동조합 기술위원회

Page 41: 클로져 소개 강의 (한국정보통신산업노동조합)

2부. 왜 클로져인가? (계속)

1. 클로져로 만들어 보는 생명 게임.(계속)2. 미로 생성기3. HDD와 RDD, 그리고 TDD4. 클로져 공부를 잘 할 수 있는 방법

한국정보통신산업노동조합 기술위원회

Page 42: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

클로져 맛보기

(println "Hello, World!")>> Hello, World!;=> nil

(+ 1 2) ;;;=> 3(+ (* 3 3) (* 4 4));=> 25

;; Var (def x 1);=> #'user/xx;=> 1

;; 키워드:a;=> :a

nil;=> nil

;; 함수 정의(defn f [x] (let [y 2] (println (+ x y)))

(f 10)=> 12

(loop [x 10] (when (> x 1) (println x) (recur (- x 2)))

;; map 함수(map inc [1 2 3])=> (1 2 3)

;; reduce 함수(reduce + [1 2 3])=> 6(reduce + 10 [1 2 3])=> 16

(1 2 3) ;; 리스트[1 2 3] ;; 벡터#{1 2 3} ;; 집합{:a 1 :b 2} ;; 맵

(first '(1 2 3)) ;; => 1(second [1 2 3] ;; => 2(nth [1 2 3] 2) ;; => 3(rest [1 2 3]) ;;=> (2 3)(count [1 2 3]) ;;=> 3({:a 1 :b 2} :a) ;;=> 1(:a {:a 1 :b 2}) ;;=> 1

(cons 3 '(1 2)) ;;=> (3 1 2)(cons 3 [1 2]) ;;=> (3 1 2)

(conj [1 2] 3) ;;=> [1 2 3](conj '(1 2) 3)) ;;=> (3 1 2)

;;익명 함수(#(* % %) 5) ;;=> 25(fn [x] (* x x) 5) ;;=> 25

평가가능한 s-expr 은 문구(Form)라고 한다 / Form이 리스트인 경우 첫 원소는 함수로 취급

Page 43: 클로져 소개 강의 (한국정보통신산업노동조합)

콘웨이의 생명게임

1. 이웃중 산 세포가 2개 미만이면 다음 세대에 죽는다.

2. 이웃중 산 세포가 2, 3개이면 다음 세대에 산다.

3. 이웃중 산 세포가 3개 초과이면 다음 세대에 죽는다.

4. 죽은 세포중 살아있는 이웃이 3개면 다음 세대에 살아난다.

한국정보통신산업노동조합 기술위원회

글라이더

Page 44: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

Page 45: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

다시 한 번 복잡성에 대해서● 자연 식별자와 인위 식별자 (natural identifier and synthetic identifier)● 자연 식별자

○ 순수 한 값 그 자체는 자기 자신을 식별한다.○ 1은 1 자기 자신을 식별한다.○ 값 그 자체로 식별이 충분하다.

● 인위 식별자○ 다른 값을 식별하기 위한 값. 매핑○ 데이타베이스의 자동증가 ID○ 정수 1을 식별하기 위한 Integer 1 개체○ 복잡성 야기○ 스레드나 프로세스간에 값과 함께 인위 식별자도 제공해야

1

1

one인위 식별자

자연 식별자

Page 46: 클로져 소개 강의 (한국정보통신산업노동조합)

한국정보통신산업노동조합 기술위원회

생명게임을 구현하는 3가지 방식● 인덱스 방식

○ 좌표를 인덱싱 방식으로 표현○ 코드 설명

● 시퀀스 방식○ 좌표를 시퀀스 방식으로 표현○ 코드 설명

● 자연 식별자 방식○ 좌표가 왜 필요해?○ 코드 설명 p.138 ~ p.145

Page 47: 클로져 소개 강의 (한국정보통신산업노동조합)

; emtpy-board

(repeat 5 "x") ;=> ("x" "x" "x" "x" "x")(vec (repeat 5 "x")) ;=> ["x" "x" "x" "x" "x"](repeat 5 (vec (repeat 5 "x")))=> (["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"])(vec (repeat 5 (vec (repeat 5 "x"))))=> [["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"] ["x" "x" "x" "x" "x"]]

(defn empty-board [w h] (vec (repeat w (vec (repeat h nil)))))

(emtpy-board 6 6)=> [[nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil]]

; populate

(assoc {} :key1 "value1") ;=> {:key1 "value1"}(assoc {:a 1 :b 2} :c 3) ;=> {:a 1 :b 2 :c 3}(assoc {:a 1 :b 2} :a 10) ;=> {:a 10 :b 2}(assoc-in {:a 1 :b {:c 3} [:b :c] 10} ;=> {:a 1 :b {:c 10}}

(assoc [0 1 2 3] 0 9) ;=> [9 1 2 3](assoc-in [0 1 [2 3]] [2 0] 10) ;=> [0 1 [10 3]](assoc-in (empty-board 6 6) [0 0] :on)=> [[:on nil nil nil nil] [nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil nil nil]]

(reduce + [1 2 3]) ;=> 6(reduce + 10 [1 2 3]) ;=> 16(reduce #(+ %1 %2) 10 [1 2 3]) ;=> 16(reduce (fn [acc n] (+ acc n)) 10 [1 2 3]) ;=> 16;(fn [10 1] (+ 10 1)) => 11;(fn [11 2] (+ 11 2)) => 13;(fn [13 3] (+ 13 3)) => 16

한국정보통신산업노동조합 기술위원회

Page 48: 클로져 소개 강의 (한국정보통신산업노동조합)

(cons 1 [2]) ;=> [1 2](reduce #(cons %2 %1) () [1 2 3]) ;=> (3 2 1); #(cons 1 ()) => (1); #(cons 2 (1)) => (2 1); #(cons 3 (2 1)) => (3 2 1)

(reduce #(assoc %1 %2 :on) [1 2 3] [0 2]) ;=> [:on 2 :on];#(assoc [1 2 3] 0 :on) => [:on 2 3];#(assoc [:on 2 3] 2 :on) => [:on 2 :on]

(reduce #(assoc-in %1 %2 :o) [[:x :x :x] [:x :x :x]] [[0 2] [1 2]]) ;=> [[:x :x :o] [:x :x :o]];#(assoc [[:x :x :x] [:x :x :x]] [0 2] :o) => [[:x :x :o] [:x :x :x]];#(assoc [[:x :x :o] [:x :x :x]] [1 2] :o) => [[:x :x :o] [:x :x :o]]

(reduce (fn [board coordinate] (assoc-in board coordinate :on)) [[1 2 3] [4 5 6]] [[0 2] [1 2]]) ;=> [[:x :x :o] [:x :x :o]]

(defn populate [board living-cells] (reduce (fn [board coordinates] (assoc-in board coordinates :on)) board living-cells))

(def glider (populate (empty-board 6 6) #{[2 0] [2 1] [2 2] [1 2] [0 1]}))=> [[nil :on nil nil nil nil] [nil nil :on nil nil nil] [:on :on :on nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil]]

한국정보통신산업노동조합 기술위원회

Page 49: 클로져 소개 강의 (한국정보통신산업노동조합)

; neighbours

(for [x [1 2 3]] x) ;=> (1 2 3)

(for [x [:a :b :c] y [1 2 3] ] [x y]);=> ([:a 1] [:a 2] [:a 3] [:b 1] [:b 2] [:b 3] [:c 1] [:c 2] [:c 3] )

(for [x [:a :b :c] y [1 2 3] :when (odd? y)] [x y]);=> ([:a 1] [:a 3] [:b 1] [:b 3] [:c 1] [:c 3] )

(defn neighbours [[x y]] (for [dx [-1 0 1] dy [-1 0 1] :when (not= 0 dx dy)] [(+ dx x) (+ dy y)]))

(neighbours [1 1]);=> ([0 0] [0 1] [0 2] [1 0] [1 2] [2 0] [2 1] [2 2])

; count-neighbours

(get [1 2 3] 0) ;=> 1(get-in [[1 2 3] [4 5 6]] [1 1]) ;=> 5

(filter even? [1 2 3 4 5]) ;=> [1 3 5]

(defn count-neighbours [board loc] (count (filter #(get-in board %) (neighbours loc))))

(count-neighbours glider [2 2]);=> 2

한국정보통신산업노동조합 기술위원회

Page 50: 클로져 소개 강의 (한국정보통신산업노동조합)

; indexed-step

(loop [x 10 y 1] (when (> x 1) (println (* x y)) (recur (- x 2) (inc y))))

(let [n 1] (cond (> n 0) "positive" (< n 0) "negative" :else "zero"))

(defn indexed-step [board] (let [w (count board) h (count (first (board)))] (loop [new-board board x 0 y 0] (cond (>= x w) new-board (>= y h) (recur new-board (inc x) 0) :else (let [new-liveness (case (count-neighbours board [x y]) 2 (get-in board [x y]) 3 :on nil)] (recur (assoc-in new-board [x y] new-liveness) x (inc y)))))))

(let [n 7] (case (mod 7 3) 0 "zero" 1 "one" 2 "two"))

(inexed-step gliber)=> [[nil nil nil nil nil nil] [:on nil :on nil nil nil] [nil :on :on nil nil nil] [nil :on nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil nil nil nil]]

(iterate inc 1) ;=> 자연수(take 5 (iterate inc 1)) ;=> (1 2 3 4 5)(nth (iterate inc 1) 8) ;=> 9(dec (nth (iterate inc 1) 8)) ;=> 8(-> (iterate inc 1) (nth 8) dec ) ;=> 8

(-> (iterate indexed-step glider) (nth 8) pprint)=> [[nil nil nil nil nil nil] [nil nil nil nil nil nil] [nil nil nil :on nil nil] [nil nil nil nil :on nil] [nil nil :on :on :on nil] [nil nil nil nil nil nil]]

한국정보통신산업노동조합 기술위원회

Page 51: 클로져 소개 강의 (한국정보통신산업노동조합)

; step

(concat [1 2 3] [4 5 6])=> (1 2 3 4 5 6)(concat (map reverse [[123] [4 5 6]]));=> (3 2 1 6 5 4)(mapcat reverse [[123] [4 5 6]]);=> (3 2 1 6 5 4)

(frequencies [:a :a :b :a]) ;=> {:a 3, :b 1}

(def cells #{[2 1] [1 3] [3 3]})

(mapcat neighbours cells);=> ([1 0] [1 1] [1 2] [2 0] [2 2] [3 0] [3 1] [3 2] [0 2] [0 3] [0 4] [1 2] [1 4] [2 2] [2 3] [2 4] [2 2] [2 3] [2 4] [3 2] [3 4] [4 2] [4 3] [4 4])

(frequencies (mapcat neighbours cells));=> {[3 2] 2, [4 3] 1, [1 0] 1, [2 2] 3, [4 4] 1, [1 1] 1, [2 3] 2, [3 4] 1, [1 2] 2, [2 4] 2, [0 2] 1, [0 3] 1, [1 4] 1, [0 4] 1, [3 0] 1, [3 1] 1, [4 2] 1, [2 0] 1}

(for [[a b] {:a 1, :b 2}] a) ;=> (:a :b)(for [[a b] {:a 1, :b 2} :when (= b 2)] a) ;=> (:b)(for [[a b] {[1 2] 2, [2 3] 1} :when (= b 2)] a) ;=> ([1 2])(for [[loc n] (frequencies (mapcat neighbours cells)) :when (= n 3)] loc);=> ([2 2])

(#{1 2 3} 1) ;=> 1(#{1 2 3} 3) ;=> 3(#{1 2 3} 4) ;=> nil

(for [a #{1 2 3} :when (#{2 3 4} a)] a) ;=> (2 3)

(for [[loc n] (frequencies (mapcat neighbours cells)) :when (or (= n 3) (and (= n 2) (cells loc)))] loc);=> ([2 2])

(defn step [cells] (set (for [[loc n] (frequencies (mapcat neighbours cells)) :when (or (= n 3) (and (= n 2) (cells loc)))] loc)))

한국정보통신산업노동조합 기술위원회

Page 52: 클로져 소개 강의 (한국정보통신산업노동조합)

인덱스/값 방식 코드 비교

인덱스 방식 코드 - 인위적 식별자 (defn indexed-step [board] (let [w (count board) h (count (first (board))] (loop [new-board board x 0 y 0] (cond (>= x w) new-board (>= y h) (recur new-board (inc x) 0) :else (let [new-liveness (case (count-neighbours board [x y]) 2 (get-in board [x y]) 3 :on nil)] (recur (assoc-in new board [x y] new-liveness) x (inc y)))))))

16줄

값 방식 코드 - 자연적 식별자

(defn step [cells] (set (for [[loc n] (frequencies (mapcat neighbours cells)) :when (or (= n 3) (and (= n 2) (cells loc)))] loc)))

5줄

한국정보통신산업노동조합 기술위원회

Page 53: 클로져 소개 강의 (한국정보통신산업노동조합)

왜 이런 차이가 발생하는가?

한국정보통신산업노동조합 기술위원회

Page 54: 클로져 소개 강의 (한국정보통신산업노동조합)

자연적/인위적 식별자 방식 코드 비교● 생명 게임 규칙에서는 단지 산 세포, 이웃, 죽은 세포(살아있는 세포가 아닌 것) 등만이 표현되고 있다. 결국 산 세포와 이웃만이 핵심 개념이고, 이것만으로 생명 게임은 표현된다.

● 인덱스 방식 코드가 복잡해진 이유○ 인덱스는 인위적 식별자○ 행과 열, 그리고 인덱스 등은 원래 생명 게임의 규칙을 설명하던 문장에서는 나타나지 않았다.

○ 원래 생명게임의 규칙에는 없었던 행과 열이라는 개념이 절차적 사고 방식에 의한 모델링에 의해 추가되어서 복잡해진 것이다.

● 값 방식 코드가 단순했던 이유○ 값은 자연적 식별자○ 살아있는 세포와 이웃만이 코드에서 표현되고 있다. 이들이 바로 값, 즉 entity이다.○ 이 값은 단순하게 튜플로 표현된다.○ 산 세포들의 연대기적 계열이 곧 생명 게임임.

● 교훈○ 결국 인위적 식별자는 우연적 복잡성이기에 제거 가능 : 이것은 코딩 이전에 우리의 사고 방식을 바꿈으로서 가능

○ 데이타 모델링시 값(entity)에 의하지 않는다면, 본질적인 것에 의하지 않는다면, 클로져 코딩이라고 하더라도 예전의 프로그래밍 방식으로 돌아가게 됨.

○ OOP 디자인 방식은 우연적 복잡성이 포함되는 것을 막는데 매우 취약하다.○ 클로져는 인위적 식별자라는 우연적 복잡성을 야기하는 요소를 잘 피해갈 수 있는 언어

한국정보통신산업노동조합 기술위원회

Page 55: 클로져 소개 강의 (한국정보통신산업노동조합)

2부. 왜 클로져인가? (계속)

1. 클로져로 만들어 보는 생명 게임.(계속)2. 미로 생성기 : 복잡성과 단순성 이야기3. HDD와 RDD, 그리고 TDD4. 클로져 공부를 잘 할 수 있는 방법

한국정보통신산업노동조합 기술위원회

Page 56: 클로져 소개 강의 (한국정보통신산업노동조합)

미로 발생기

윌슨의 미로 발생기 알고리즘

1. Randomly pick a location and mark it as visited.2. Randomly pick a location that isn’t visited yet—if there’s none, return

the maze.3. Perform a random walk starting from the newly picked location until

you stumble on a location that is visited—if you pass through a location more than once during the random walk, always remember the direction you take to leave it.

4. Mark all the locations of the random walk as visited, and remove walls according to the last known “exit direction.”

5. Repeat from 2.

한국정보통신산업노동조합 기술위원회

Page 57: 클로져 소개 강의 (한국정보통신산업노동조합)

미로 발생기

윌슨의 미로 발생기 알고리즘기본 원리 : 벽으로 바둑판같이 된 미로의 벽을 허물며 생성

1. 임의의 좌표를 골라서 방문 표시한다.

2. 방문하지 않은 임의의 좌표를 고른다 - 만약 없다면 미로 출력

3. 2에서 고른 좌표에서 출발하여 방문 표시된 위치까지 랜덤 걷기한다 - 랜덤 걷

기중 한 위치를 2번 이상 지난다면, 항상 그 방향을 기억한다.

4. 랜덤 걷기한 모든 위치를 방문표시하고, 출구 방향에 따라 벽을 제거한다.

5. 2로 돌아간다.

한국정보통신산업노동조합 기술위원회

Page 58: 클로져 소개 강의 (한국정보통신산업노동조합)

미로 발생기 클로져 코드

(defn maze [walls] (let [paths (reduce (fn [index [a b]] (merge-with into index {a [b] b [a]})) {} (map seq walls)) start-loc (rand-nth (keys paths))] (loop [walls walls unvisited (disj (set (keys paths)) start-loc)] (if-let [loc (when-let [s (seq unvisited)] (rand-nth s))] (let [walk (iterate (comp rand-nth paths) loc) steps (zipmap (take-while unvisited walk) (next walk))] (recur (reduce disj walls (map set steps)) (reduce disj unvisited (keys steps)))) walls))))

한국정보통신산업노동조합 기술위원회

Page 59: 클로져 소개 강의 (한국정보통신산업노동조합)

미로 발생기영어와 클로져 코드 비교

한국정보통신산업노동조합 기술위원회

Page 60: 클로져 소개 강의 (한국정보통신산업노동조합)

;;; 자바 표현Class Location { private int x, y; public Location (int x, int y) { this.x = x; this.y = y; } int getx() { return x; }

int gety() { return y; }}

Location loc = new Locatin(0, 0);

Class Wall { private Location[2] locs; public Wall(Location loc1, Location loc2) { this.locs[0] = loc1; this.locs[1] = loc2; } ...}

Wall wall = new Wall(new Location(0, 0), new Location(1, 0));

Class Maze { private ArrayList walls = new ArrayList(); public void add(Wall wall) { walls.add(wall); }}...

Maze maze = new Maze();maze.add(wall1);maze.add(wall2);maze.add(wall3);

...

;;; 클로져 표현

; location[0 0]; wall#{[0 0] [1 0]}; maze#{#{[0 0] [1 0]} #{[1 0] [2 0]} #{[2 0] [3 0]} ...}

한국정보통신산업노동조합 기술위원회

Page 61: 클로져 소개 강의 (한국정보통신산업노동조합)

언어 상호 번역 규칙Rule of English Translation

1. 알고리즘을 말(인간언어)로 기술하라.2. 기술된 말을 코드로 적는다.3. 코드를 다시 말(인간언어)로 번역한다.4. 3과 1을 비교하라.

피터 노빅의 Tutorial on Good Lisp Programming 중에서

한국정보통신산업노동조합 기술위원회

Page 62: 클로져 소개 강의 (한국정보통신산업노동조합)

Rosetta code 코드 길이 비교

http://blog.wolfram.com/2012/11/14/code-length-measured-in-14-languages/

rosettacode.org

● 여러가지 문제들에 대해 다양한 언어로 풀어보는 싸이트.

● 같은 문제에 대해 각 언어간 해법을 비교할 수 있음.

● 현재 667개의 문제가 497개의 언어로 코딩.

● 다음 표는 14 개 언어의 코드 길이의 상대적 비율을 나타냄.

한국정보통신산업노동조합 기술위원회

Page 63: 클로져 소개 강의 (한국정보통신산업노동조합)

복잡성과 단순성“복잡성은 저의 1차적 관심사인데요, 제 생각에 클로저는 이것을 잘 처리하고 있다고 생각합니다. 코어 수준에서 클로저는 매우 단순합니다. 클로저는 명백한 복잡성과 우연적 복잡성 둘 다 줄이는데 집중합니다. 특히 후자는 문제 영역이 아닌 해결 영역-언어나 도구-에서 나오는 복잡성입니다. 제 생각에 프로그래머들이 우연적 복잡성에 익숙해져 있는데요, 특히 단순한 것을 친숙한 것 혹은 간결한 것과 혼동하고 있지요. 그래서 복잡성을 만나면, 그것을 극복해야 할 도전과제로 여깁니다. 사실 그건 제거해야 할 장애물인데요. 복잡성을 극복하는 것은 잘 돼지 않습니다. 그건 낭비입니다.”

“우리는 기존의 객체지향 언어에 내재되어 있는 우연적 복잡성 때문에 매우 힘듭니다. 그 복잡성은 문법적인 것도 있고, 의미론적인 것도 있는데, 제 생각에 우리가 이런 사실을 전혀 모르고 있다는 거에요. 저는 '올바른 일을 한다는 것(doing the right thing)이 단지 관례나 훈련에 의해 되는 것이 아니라, 저절로 자연스럽게 되게 하고 싶었어요. 저는 강고한 동시성과 기존 자바 라이브러리와의 거대한 상호운영성을 원했습니다.” 리치 히키 인터뷰

한국정보통신산업노동조합 기술위원회

Page 64: 클로져 소개 강의 (한국정보통신산업노동조합)

단순성과 복잡성

● 단순성(Simplexity) <-> 복잡성(Complexity)

● 쉬움(Easy) <-> 어려움(Difficulty)

● 단순성 쉬움

● 사람은 훈련을 통해서 어려운 것을 쉬운 것으로 만들어 낸다.○ 그리고 이것에 익숙해지고 친숙해진다.

● 그러나 어려운 것의 복잡성이 본질적으로 사라진 것은 아니다.○ 사실은 단지 우리의 뇌가 그만큼 복잡해진 것.○ 필수 다양성의 법칙!

● 어려운 것 속에 있는 복잡성은 극복의 대상이 아니라 제거의 대상이다.

한국정보통신산업노동조합 기술위원회

Page 65: 클로져 소개 강의 (한국정보통신산업노동조합)

훈련은 중요하다. 그러나 보다 본질적인 것에 집중하라!.

한국정보통신산업노동조합 기술위원회

Page 66: 클로져 소개 강의 (한국정보통신산업노동조합)

왜?

한국정보통신산업노동조합 기술위원회

Page 67: 클로져 소개 강의 (한국정보통신산업노동조합)

우리가 인생에서 쏟을 수 있는 에너지는 한정되어 있으니까.

- 리치 히키

한국정보통신산업노동조합 기술위원회

Page 68: 클로져 소개 강의 (한국정보통신산업노동조합)

2부. 왜 클로져인가? (계속)

1. 클로져로 만들어 보는 생명 게임.(계속)2. 미로 생성기3. HDD와 RDD, 그리고 TDD4. 클로져 공부를 잘 할 수 있는 방법

한국정보통신산업노동조합 기술위원회

Page 69: 클로져 소개 강의 (한국정보통신산업노동조합)

HDD(Hammock Driven Development)

● 리치 히키○ "컴퓨터는 집중하지 못하게 하는 큰 요인이다"○ "컴퓨터에서 멀리 떨어져 있어라"○ "소프트웨어에서의 가장 큰 문제는 잘못된 개념화의문제이다" (구현 단계에서의 문제가 아니다)

■ 설계 단계에서 버그 잡는 것이 가장 싸다.○ "무의식을 사용하라"

● 문제 이해하기○ 사실, 상황, 제약사항(알려진/알려지지 않은), 무지에 대한 무지를 찾는 질문, 비슷한 문제들

○ 기존의 솔루션들 이해하기○ 문제에 대한 최상의 솔루션을 점진적으로 찾는 것○ 종이 위에 문제를 기술하라

● 알아차리기○ 당신의 솔루션에 문제가 없는가? 있다면 해결해라.○ 타협점을 찾으라. 타협점이 자주 있다면 솔루션에 결함이 있다는 것.○ 타협점을 잘 이해하기 위해서는 적어도 2개의 대안을 쥐고 있어야 한다.○ 그 내용을 종이위에 적어라.

리치히키의 HDD 동영상

한국정보통신산업노동조합 기술위원회

Page 70: 클로져 소개 강의 (한국정보통신산업노동조합)

HDD(Hammock Driven Development)

● 집중 - 생각하라○ 컴퓨터는 생각 방해꾼 - 컴퓨터에서 멀리 떨어져라.○ 의식속에서 문제에 대해 많이 생각하면그 문제는 무의식속에 들어가서 처리된다.

○ 마음은 한 번에 7개 정도 아이템만에 집중할 수 있기 때문에, 나머지는 종이위에 적어라.

○ 그리고 그림을 그려라(UML로는 하지말고). ○ 이것을 반복해서 내재화하라 .○ 눈을 감고 다른 감각을 제거하고 생각에 집중하라.○ 솔루션이 나올 때까지 기다려라...○ 무의식이 응답이 없으면 다른 문제로 가라. 그리고 다시 돌아오라. 반복하라.

● 솔루션이 나온다면(유레카!)○ 검토해보고 코딩해 본다.○ 충분히 생각한 것이기 때문에 당신의 코딩은 완벽할 것이다.○ 피드백은 중요하다. 그러나 그것에 의존하지 말라.

한국정보통신산업노동조합 기술위원회

Page 71: 클로져 소개 강의 (한국정보통신산업노동조합)
Page 72: 클로져 소개 강의 (한국정보통신산업노동조합)

프로그래머 앨런과 찰스 이야기

한국정보통신산업노동조합 기술위원회

앨런과 찰스는 똑같은 프로그램을 짜고 있었다.

찰스는 문제를 고민하는데 시간을 보냈다. 관리자는 그가 책상 위에 다리를 올려놓고 커피를 마시거나 창 밖을 응시하는 모습을 자주 보았다. 가끔 컴퓨터 앞에 앉기는 했는데, 키보드 두드리는 소리로 보아 게임하는 것임을 알 수 있었다. 어느 날 관리자는 찰스가 작은 종이 위에 무언가를 열심히 적는 것을 보았는데, 빙고 게임 같지는 않지만, 그다지 의미가 있어 보이지는 않았다.

관리자는 찰스가 빈둥거리는 모습을 더 이상 두고 볼 수 없었다. 그와 면담하려고 갔는데, 그만 놀라고 말았다. 찰스가 컴퓨터 앞에서 정신없이 코드를 입력하고 있는 것이었다. 관리자는 면담을 미루고, 그를 세밀히 관찰했다. 찰스가 점심까지 거르고, 일주일에 이삼일은 야근하는 것을 보고 내심 안심했다.

세 달이 지날 무렵, 찰스가 프로젝트를 끝냈다고 발표했다. 500줄 길이의 프로그램이었는데 , 깔끔하게 작성되었으며 사실상 프로그램의 사용성을 상당히 개선시키는 편리한 기능도 추가했다. 테스트를 통과했고, 모든 요구사항을 충족했으며 , 금방 수정할 수 있는 사소한 실수 하나를 제외하면 성능도 뛰어났다.

관리자는 감명받았다 . 하지만 소스 코드를 읽으면서, 원래 생각했던 것보다 프로젝트가 훨씬 간단했다는 것을 깨달았다. 이건 초보도 풀 수 있는 수준이었던 것이다. 찰스는 하루 평균 5줄의 코드를 짰는데, 이는 평균을 웃돌기는 했지만, 프로그램이 워낙 단순하다 보니 특별한 생산성은 아닌 것 같았다. 게다가 관리자는 찰스가 처음 두 달을 농땡이 부린 기억이 떠올랐다.

찰스는 다음 연봉 협상에서 물가인상률의 절반에 불과한 봉급 인상을 통보받고, 승진도 하지 못했다. 실망한 찰스는 회사를 그만뒀다.

Page 73: 클로져 소개 강의 (한국정보통신산업노동조합)

프로그래머 앨런과 찰스 이야기

한국정보통신산업노동조합 기술위원회

앨런은 세 명의 프로그래머와 팀을 이루어 작업에 착수했고, 예비 보고서와 문제 분석서를 양산해냈다 . 그리고나서 코딩을 시작했는데 , 근무시간의 반은 코딩하고 반은 회의실에서 여러 모듈 사이의 인터페이스를 토론했다.

2 달이 지났다. 앨런은 구현 일정을 배포했다. 그에 따르면 앞으로 2개월 안에 테스트 버젼을 출시할 것이다.

세 달이 지날 무렵, 앨런팀은 주요 모듈 4개 중 2개를 완성했다. 완성 모듈을 테스트하면서 동시에 미완성 모듈을 구현할 수 있을 것이다. 3주가 지나자 예비 버젼이 완성되었다 . 그리고 결함 목록도 제출되었다. 테스트 결과, 버그와 결함이 많이 발견되었다 . 앨런은 예비 버젼이므로 놀랄 일은 아니라고 했다. 2달이 지나고 최종 버젼이 완성되었다 . 전체 2500줄이었는데 , 요구사항을 만족하는 것 같았지만, 기능 한 두 가지를 빼먹었으며 , 데이터 입력 형식이 매우 까다로왔다 . 이를 위해 입력 담당자를 따로 두어야 했다. 프로그램은 유지보수 프로그래머에게로 넘겨지고, 빠진 기능은 그에 의해 완성되었다 .

회사는 프로젝트를 제 시간에 마쳤다고 그를 칭찬했다. 관리자는 프로그램 소스코드를 보고 회사표준 양식을 준수했다는 것을 확인했지만 , 프로그램은 너무 난해한 것을 보고 애초에 생각했던 것 보다 문제가 훨씬 복잡했다는 것을 깨달았다. 관리자는 앨런을 다시 한 번 격려했다.

앨런 팀은 프로그래머 1명당 3줄의 코드를 작성했다. 평균을 밑돌지만, 문제가 난해했던 것을 고려하면 특별한 것은 아니라고 간주할 수 있었다. 앨런은 봉급이 엄청 올랐고, 시스템 분석가로 승진했다.

Page 74: 클로져 소개 강의 (한국정보통신산업노동조합)

이것은 천재들의 방식인가?

● 컴퓨터에서 떨어져서 생각하는 것이 중요○ 산책하기○ 조용한 곳에서 커피 한 잔 하기○ 곰 인형 끌어안고 속으로 대화하기○ ...

● 머리속에서 생각하는 것도 훈련이다!

한국정보통신산업노동조합 기술위원회

Page 75: 클로져 소개 강의 (한국정보통신산업노동조합)

RDD(REPL Driven Development)

● REPL○ Read, Evaluate, Print and Loop

● RDD 장점○ TDD 보다 빠른 피드백 - 우수한 설계로 인도○ 현재 구동중인 프로그램의 상태에 대한 확인 및 변경 가능

● RDD 단점○ 회귀 테스트가 되지 않는다.○ 회귀 테스트는 BDD로 보완.

한국정보통신산업노동조합 기술위원회

Page 76: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져에서의 RDD와 TDD

요구 명세 인수 테스트

분석 시스템 테스트

디자인 통합 테스트

구현 단위 테스트 RDD

BDD

TDD

한국정보통신산업노동조합 기술위원회

Page 77: 클로져 소개 강의 (한국정보통신산업노동조합)

진화적 설계의 약점

● 진화적 설계(XP, TDD)○ 시스템을 구현하면서 동시에 디자인도 개선해 나가는 것.

○ 디자인은 구현의 과정의 일부이다.○ 프로그래밍이 점진적으로 진화하면서 설계도 변한다.

● 언덕 오르기(선택 편향)○ 지금 현재 여기보다 높은 곳으로 최대한 빨리 이동하는 방식

○ 출발점에 따라 국소 극대라는 정상에 오르거나 전역 극대에 오르게 된다.

● 진화적 설계의 약점은 최초 출발점에 따라 국소 극대에 오를 가능성이 있다는 것.

한국정보통신산업노동조합 기술위원회

Page 78: 클로져 소개 강의 (한국정보통신산업노동조합)

진화적 설계의 약점● 진화는 좋은 설계를 보장하지 않는다.● 인간의 눈보다 오징어의 눈이 설계상으로는 더 우수하다.

● 인간의 눈○ 망막이 신경 다발 아래 있다.○ 신경다발이 모여서 망막을 뚫고 지나가면서 맹점을 만든다.

● 오징어의 눈○ 망막이 신경 다발 위에 있다.○ 신경다발이 망막 아래 모이기 때문에 망막에는 맹점이 생기지 않는다.

● 다른 예들○ 돌고래의 숨구멍○ 캥거루의 적꼭지○ 기린의 출산

1. 망막. 2. 시신경. 3. 신경 다발.4. 맹점

A. 인간의 눈 B. 오징어의 눈

한국정보통신산업노동조합 기술위원회

Page 79: 클로져 소개 강의 (한국정보통신산업노동조합)

2부. 왜 클로져인가? (계속)

1. 클로져로 만들어 보는 생명 게임.(계속)2. 미로 생성기3. HDD와 RDD, 그리고 TDD4. 클로져 공부를 잘 할 수 있는 방법

한국정보통신산업노동조합 기술위원회

Page 80: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져 공부를 잘하는 방법● 4Clojure.com가 Clojure 공부에 좋은 이유

○ Learn By Doing : 코딩하면서 코딩을 배운다.○ 문제를 풀고 나면 다른 사람이 푼 것을 볼 수 있다. 이것은 특히 함수형 프로그래밍에 아직 익숙하지 않은 사람들에게 좋다. 다음 사람들을 Follow하면 좋은 코드를 볼 수 있다 : maximental, hypirion, jafingerhut, chouser

○ 테스트케이스가 잘 정의되어 있어, 단순히 문제의 해설에 대한 오해를 차단한다. 또한 생각지 못한 경우에 대해 대비하게 된다.

○ Timeout이 걸려있다. 그래서 무식한 방식으로 풀면 Timeout에 걸린다. 좀 더 전략적인 방법을 고안해야 한다.

○ Clojure.core 함수들에 익숙해 진다 : map, map-indexed, keep, keep-indexed, some, reduce, frequencies, merge-with, condp

○ 인수분해 기법을 배우게 된다.○ HDD의 맛을 느끼게 한다.

● 4Clojure 문제들 총 153문제○ Elementary : 32 Easy : 53○ Medium : 45 Hard : 23

한국정보통신산업노동조합 기술위원회

Page 81: 클로져 소개 강의 (한국정보통신산업노동조합)

클로져 공부를 잘하는 방법● 코드 읽기 (좋은 오픈 소스를 읽기)

○ nREPL■ 소켓 통신과 프로토콜 구현, REPL 동작방식에 대한 이해.

○ RING■ 클로져 웹 어플리케이션 라이브러리. HTTP 프로토콜, 파싱, 핸들러-미들웨어 패턴

○ Leiningen■ 클로져 프로젝트 관리 툴. 클로져와 자바와의 관계, 빌드 과정의 이해, 플러그인 작성

○ Storm■ 분산 실시간 계산 플랫폼. 클로져의 우수한 동시성 관련 기능이 유기적으로 잘 사용됨

"사람들은 내가 쉽게 작곡한다고 생각하지만 이건 실수라네. 단언컨대 친구여, 나만큼 작곡

에 많은 시간과 생각을 바치는 사람은 없을 걸세. 유명한 작곡가의 음악 치고 내가 수십 번

에 걸쳐 꼼꼼하게 연구하지 않은 작품은 하나도 없으니 말이야."

- 모짜르트가 친구에게 보낸 어느 편지에서

한국정보통신산업노동조합 기술위원회

Page 82: 클로져 소개 강의 (한국정보통신산업노동조합)

● 한국정보통신산업노동조합○ it.nodong.net

● 한국 클로져○ clojure.or.kr

● 4Clojure○ 4clojure.com

● 클로져○ clojure.org

● Lisp을 좋아하는 사람들의 그룹○ K-Lisper

강사 : 박 상규 ([email protected])

한국정보통신산업노동조합 기술위원회