왜 리습(Lisp)인가?

chanwooyoo의 이미지

블로그에 올리려고 쓴 글인데.. 리습에 관심있는 분들이 많이 생기셨으면 해서.. 여기에도 한 번 옮겨 봅니다. KLDP에 사실 별로 와 본 적이 없고 처음 써 보는 글이라 좀 긴장되네요. 분류도 여기가 맞는지도 잘 모르겠구요. ㅠㅠ 썼던 걸 그대로 옮겨서 말투가 반말투이니 이해해주세요;

-------------------------

리습은 특별하다. 여러 가지 언어들이 자신은 특별하다고 주장하지만, 리습은 그런 모든 언어들이 가질 수 없는 점을 가졌다는 점에서 특별하다. 아마 프로그래밍 언어를 크게 가른다면, '리습 / 그 외의 언어들'로 가를 수 있을 것이다. 허무맹랑한 주장이라고 생각하는가? 한 번 그 이유를 들어보기 바란다.



몇 가지 비유를 들어보겠다.



만일 요술램프의 지니가 당신에게 한 가지 소원만 들어준다고 했다고 하자. 당신은 어떤 소원을 빌겠는가? 예쁜 여자친구? 어마어마한 돈? 영원한 생명? 글쎄. 나 같으면 어떤 소원이든 들어주는 반지를 달라고 하겠다.



무협지에서 어떤 사람의 내공이 가장 강한가? 오랫동안 수련한 사람? 글쎄. 북명신공을 지녀서 다른 사람의 내공을 흡수하는(악랄할 수도 있지만) 능력을 가진 녀석의 내공이 시간이 지남에 따라 가장 강해지지 않을까?



드래곤볼에서 어떤 종족의 특성이 가장 좋다고 생각하는가? 재생이 되는 나메크인? 변신이 되는 프리더의 종족? 단연 샤이어인이다. 전투를 거듭할 때마다 상대만큼 강해지는 녀석들이기 때문이다.



마찬가지다.



어떤 언어가 한 가지 특성을 마음대로 가질 수 있다면 어떤 특성을 가지는 게 좋을까? 다른 언어의 어떤 장점이든 가져올 수 있는 특성이 제일 좋지 않겠는가? 그리고 이게 바로 리습이 가진 능력이다.



C를 보라. 객체 지향 프로그래밍을 하기 위해서는 구조체와 함수포인터를 사용해서 흉내내는 수 밖에 없다. define_class 라는 추상화를 만들어낼 능력이 없기 때문이다.



자바를 보라. foreach 라는 추상화를 사용하기 위해 자바 프로그래머들은 1.5 버전까지 기다려야만 했다. 언어에서 foreach 라는 추상화를 만들어 낼 능력을 가지고 있지 못하기 때문이다.



리습은 '매크로'라는, C의 매크로와는 매우 다른, 추상화 능력을 가지고 있다. 그리고 이 매크로를 통해 객체 지향 프로그래밍, lazy evaluation, continuation, 하스켈에서 자랑으로 여기는 monad 등등의 개념들을 라이브러리로 흡수해 왔다. 언어 자체는 전혀 변경하지 않고서! 이것은 이렇게 할 수 있다는 주장이 아니라, 역사적인 사실을 말하는 것 뿐이다. 1980년대 후반, 객체 지향 개념이 유행하자 리습에서는 OOP를 라이브러리로 추가했다. OOP를 라이브러리로 추가한다는 게 무슨 말인지 이해가 안 간다면, 다음과 같은 예가 도움이 될 것이다. 당신이 수학에 관한 라이브러리를 사용한다면 sin, cos 같은 추상화를 사용할 수 있게 된다. 그렇지 않은가? 마찬가지로 OOP에 관한 라이브러리를 사용한다면 define_class 라는 추상화를 사용할 수 있게 되는 것이다.



다른 언어에서 어떤 매력적인 개념이 등장하든지 리습은 바로 그 개념을 흡수할 수 있다. 그 개념은 라이브러리 형태로 추가되기 때문에 언어의 코어는 전혀 커지지 않고, backward compatibility도 완벽하게 유지된다. 라이브러리가 추가되면 언어에 새로운 문법이 추가될 거라고 생각하는가? 어떤 사람들은 리습의 매크로가 새로운 문법을 추가하는 거라고 생각하는데 이는 착각이다. 리습에는 operator 뒤에 operand 들이 온다는 문법 - 예를 들면 (operator operand1 operand2 ...) - 외에 다른 문법이 없다. 방금 당신은 리습에 존재하는 모든 문법을 배운 것이다.



foreach와 같은 새로운 제어 구조를 만들어내는 것은 Smalltalk와 Haskell도 할 수 있다. 하지만, 어떤 개념/추상화든지 가져올 수 있는 능력을 가진 것은 리습 뿐이다. 리습, 스몰토크, 하스켈이 신의 언어라고 불리는 세 가지 언어지만, 리습은 언어 자체를 변경시키지 않고도 어떤 개념이든 흡수할 수 있다는 점에서 다른 모든 언어들과 근본적으로 다르다. 그리고 이런 차이를 만들어내는 것은 다음 세 가지이다. 어떤 언어가 리습인지를 판단할 때 다음과 같은 세 가지를 만족한다면 리습이라고 할 수 있을 것이다.



1. 데이터와 코드의 형태가 같다(homoiconicity). 리습이 어떤 개념이든 쉽게 흡수할 수 있는 것은 단지 매크로 때문만은 아니다. 여기서 나열하는 1번과 2번 특성이 매크로의 작성을 극도로 쉽게 만들어 준다.



2. 문법이 (하나밖에) 없다. Paul Graham 같은 사람들은 ‘리습에는 문법이 없다.’라고 말하기도 한다. (operator operand1 operand2 ...) 이게 리습 문법의 전부다.(이것이 다른 메타 프로그래밍이 가능한 언어들과 리습을 차별화하는 요소이다. 리습에는 파서가 없다. 리습의 코드 자체가 트리 형태로 되어 있기 때문에 메타 프로그래밍을 통해 조작해야 하는 abstract syntax tree가 어떤 형태일지 고민할 필요가 없다. 코드 그대로가 곧 그것이기 때문이다. 프로그래머는 늘 보던 코드 형태 그 자체를 조작하면 되기 때문에 메타 프로그래밍을 통해 어떤 결과가 나올지를 예상하는 것이 아주 쉽다. 반면에 '파서가 있는' 다른 언어들의 경우에는 코드가 파싱된 결과물인 트리를 조작한 후 그 트리가 unparse된 결과가 자신이 의도한 코드가 되도록 메타 프로그래밍을 해야 한다. 평소에 익숙히 봐오던 프로그램 코드이지만 파싱된 결과물이 어떤 구조의 트리로 바뀌는지 알게 뭐란 말인가? 이 같은 작업은 매우 '비직관적이고', '어려운' 일이다. 프로그래머가 평소에 봐오던 코드와 최대한 비슷한 형태로 코드를 데이터처럼 다루기 위해서 스트링을 사용할 수도 있지만, 이 같은 방법을 사용할 경우 inadvertent variable capture를 피할 수 있는 방법을 보통 제공하지 않기 때문에 구멍난 추상이 되기도 쉽고, 결정적으로 스트링은 트리처럼 구조적으로 다루기가 용이하지 않기 때문에 조금이라도 복잡한 메타 프로그래밍을 제대로 하기란 쉽지 않다.)



3. 매크로를 가지고 있다.



if 문, 가비지 콜렉션, REPL(대화형 셀)을 이용한 interactive programming, functional programming 등등은 모두 리습에서 처음 등장한 개념들이다. 다른 언어들이 이 같은 개념을 흡수하며 자신을 acceptable Lisp, 또는 alternative of Lisp이라고 광고한다. 파이썬이나 루비 같은 언어들이다. 하지만 위에서 나열한 리습의 가장 핵심적인 특성 세 가지는 이상하게도 어떤 언어도 흡수하지 못하고 있다. 왜라고 생각하는가? 저 특성들을 흡수하고 나면 그 언어는 리습이 되어버리기 때문이다.



예전에 다른 포스트에서 리습을 배우면 여러 가지 언어에 존재하는 개념들을 한 번에 배울 수 있다고 말한 적이 있다. 이제 그 이유가 왜인지 알았으리라 생각한다. 리습은 다른 언어가 장점으로 내세우는 개념을 손쉽게 흡수해버리기 때문에 멀티 패러다임 언어가 되기 쉽다. ‘리습으로는 함수형 프로그래밍을 해야 하고 객체 지향 프로그래밍은 못할 거야’라던가, ‘리습에서는 반복을 위해 재귀를 사용해야만 하고 루프문 같은 건 사용하지 못하겠지’와 같은 생각들은 모두 착각이다. 당신이 어떤 라이브러리를 사용하는지에 따라 리습은 어떤 모습의 언어도 될 수 있다. OOP 라이브러리를 사용한다면 객체 지향 방식으로 프로그래밍 할 수 있는 것이다.



하스켈에서 내세우는 monad 라는 개념을 배우고 싶은가? 루비나 파이썬, 스몰토크를 살펴봐서는 알 수 없을 것이다. 그렇다고 모나드가 무엇인지 배우기 위해 하스켈을 익힐 필요는 없다. 리습을 아는 사람이라면 리습을 통해 http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/]로 이동합니다." target="_blank" href="http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/">모나드의 개념을 익힐 수도 있고, 실제로 모나드 라이브러리를 사용할 수도 있다.



라이브러리의 수? 좋은 IDE? 약간 더 좋은 표현력? 이런 것들은 다 피상적인 것으로 금방 따라잡힐 수 있는 것들이다. 실제로 모든 C/C++ 라이브러리는 Common Lisp에서 호출 가능하고, 모든 자바 클래스는 Clojure라는 리습에서 사용 가능하다.(Clojure는 JVM 위에서 돌아가는 리습으로, 자바 코어나 자바 라이브러리들을 번거로운 절차 없이 바로 호출 가능하다. 속도도 파이썬이나 루비와는 비교할 수 없을 정도로 빠르다.)



요약하면, 리습의 무서움은 그 잠재력에 있다. 이 글을 읽고 리습에 관심이 생겼다면 http://clojure.org/]로 이동합니다." target="_blank" href="http://clojure.org/">Clojure라는 리습을 한 번 살펴보기 바란다. 내가 아는 한 가장 아름답고, 강력한 언어다. Erlang의 강점인 concurrent programming을 위한 특성까지도 가지고 있다. http://pragprog.com]로 이동합니다." target="_blank" href="http://pragprog.com">pragprog.com에서 http://pragprog.com/titles/shcloj/programming-clojure]로 이동합니다." target="_blank" href="http://pragprog.com/titles/shcloj/programming-clojure">책도 나와 있으니 공부하기도 어렵지 않다. 가장 최근에 나온 리습 dialect이기 때문에 기존의 Common Lisp이나 Scheme이 가지고 있는 단점들이 없고 정말 말끔한 느낌을 주는 언어다.



마지막으로 리습에 관련된 일화를 간단히 소개하며 끝낼까 한다. ILC 2002(International Lisp Conference 2002)중에 있었던 일이라고 한다. 출처는 다음과 같다. http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why-lisp.html]로 이동합니다." target="_blank" href="http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why-lisp.html">http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why-lisp.html



http://norvig.com/]로 이동합니다." target="_blank" href="http://norvig.com/">Peter Norvig이 ILC 2002 키노트 스피치를 맡았을 때였다. 그는 스피치에서 '파이썬이 리습이다'라는 주장을 했다고 한다.(아마도 파이썬이 리습의 대용으로 충분하다 라는 주장이었을 것으로 생각된다.) ILC 에서 키노트 스피치를 맡아 '파이썬이 리습이다'라는 주장을 펼친 것은 마치 마틴 루터가 부활절 바티칸 미사를 맡아 진행하다가 개신교를 선언한 것 마냥 놀라운 행동이라고 할 수 있다. Peter가 스피치를 마치고 질문을 받았을 때, 그 자리에 있던 http://www-formal.stanford.edu/jmc/]로 이동합니다." target="_blank" href="http://www-formal.stanford.edu/jmc/">John McCathy(리습의 창시자)가 물었다고 한다. "파이썬은 코드를 데이터처럼 다룰 수 있습니까?" Peter의 대답은 "아니오"였고 Peter는 John이 계속해서 질문하기를 기다렸지만 John은 더 이상 아무 말도 하지 않았다.



John McCathy는 루비가 리습으로부터 많은 영향을 받았다는 얘기를 듣고 루비에 대해서도 같은 질문을 한 적이 있다. 대답은 역시나 "아니오"였고, 그는 "루비가 코드를 데이터로 다루지 못한다는 점에 있어서 루비는 리습이 이미 1960년에 도달했던 지점을 아직도 따라잡지 못하고 있다."라고 말했다.



리습을 제외한 모든 언어에 물어보라. "그 언어는 코드를 데이터로 다룰 수 있습니까?" 대답은 언제나 "아니오"일 것이다. 그리고 이것이 리습이 그토록 특별한 이유이다. 코드를 데이터로 다룰 수 있다면? 당신은 어떤 추상화(OOP, monad와 같이 아래로부터 위로 쌓아올려지는 개념을 말하는 것이다. 당신이 함수 하나를 짰다면, 일련의 프로시저를 하나의 함수로 추상화한 것이다.)도 할 수 있는 능력을 갖게 된다. 그게 뭐 그리 중요하냐고? 자바 프로그래머들에게 묻고 싶다. 당신은 자바 1.5 이전에 파이썬의 for와 같은 foreach문을 만들어서 직접 사용할 수 있었는가? 할 수 없었다. Sun이 foreach를 자바에 추가해줄 때까지 기다려야만 했다. 당신은 foreach문이 무엇인지 머릿속에서 알고 있었다. 알고 있는 개념을 왜 만들거나 사용할 수 없단 말인가? 언어의 한계 때문이다. 리습에는 그런 한계가 없다. 리습은 프로그래머가 생각하는 어떤 개념도 추상화할 수 있도록 무한한 자유를 부여하는 유일한 언어다.



정말 마지막으로 ^^; 한 가지만 더 얘기하면 리습을 공부하기 위해 '컴퓨터 프로그램의 구조와 이해 (Structure and Interpretation of Computer Programs)'를 보는 사람들이 있는데, 저 책을 읽으면 그냥 프로그래밍 공부는 되겠지만, 리습의 강점인 'homoiconicity(코드와 데이터의 형태가 같음)와 매크로'를 이해하는 데는 아무 도움도 되지 않는다. 책이 그런 내용을 전혀 담고 있지 않기 때문이다. 한 마디로 저 책은 프로그래밍 공부를 위한 책이지, 리습이 가지는 고유한 특성이나 개념을 알려주는 책은 아니라는 것이다.



혹시 이 주제와 관련하여 궁금한 것이나 다른 나누고 싶은 얘기가 있다면 chanwoo.yoo@gmail.com 으로 메일을 보내주기 바란다.

gurugio의 이미지


사실 많은 해커분들이 LISP에 대해서 극찬을 해주셔서
LISP이나 scheme을 공부해보고 싶지만
제가 워낙 밑바닥에서만 있다보니 너무 어렵습니다.

부탁이 있는데요
LISP 의 좋은 개념들이 잘 계승된 대안이 뭐가 있는지 좀 알려주셨으면 합니다.
파이선이나 펄은 밑바닥 개발에 좀 힘들고
C++은 너무 복잡하고 난해합니다.

C외에 업무에도 좀 적용하면서 최신 기능들이 구현된 언어를 배워서
밑바닥개발에 적용해보고 싶습니다만
어떤 대안이 있는지 잘 모르고 있습니다.

함수형 언어들은 리눅스에서 시스템 프로그래밍이 가능한가요?
시스템콜을 호출할 수 있고, C와 서로 호출되는 언어가 뭐가 있을까요.
지금까지 이와 비슷하게 현대 언어들에 대한 토론을 봐왔지만
제 주변에 밑바닥 개발자들의 현실에는 맞지 않는것 같습니다.

----
섬기며 사랑하면 더 행복해집니다.
개인 홈페이지가 생겼습니다 http://caoskernel.org
어셈러브를 개편중입니다 http://www.asmlove.co.kr

magingax의 이미지

ACL 의 경우 win32 시스템 함수를 직접 호출해서 사용할수있습니다.
예로 DeviceIoControl 함수 같은걸 직접 콜해서 장비제어에 사용하고 있습니다.
또 진짜 속도가 필요한 이미지처리 같은경우는 C 함수로 만들어
LISP 에서 FFI 를 이용해 호출하면 됩니다.

LISP 사용자모임
http://cafe.naver.com/lisper
방송기술 개발업체
http://playhouseinc.co.kr

winner의 이미지

이 경우에는 interpreter embedding 같은 기술을 알려드려야 할 것 같아요.
Interpreter가 삽입되는 무시무시함을 달가워할런지는 모르겠습니다만...

ACL이면 아마도 Allegro Common Lisp 인 것 같은데 binary 생성이 가능한지 모르겠고, 그렇든 그렇지 않든 C에서 호출하는 것이 얼마나 쉽게 가능할런지 조금 의문입니다.

ACL이 그렇다는 것은 아닙니다만 자신을 glue 언어로 소개하는 많은 언어들이 C에서 만들어진 binary 호출이 쉽다고 강조하지만 거꾸로는 더 어렵거나 소개가 없기도 하죠.

dreamstorm의 이미지

서로 호출이란게 정확히 어떤 의미인지 모르겠네요.

보통 lisp 개발자들은 lisp 을 메인으로 하고 C 라이브러리들을 불러쓰더군요.
cffi 에는 callback 이란게 있어서 C api 가 함수포인터를 받을경우 lisp 함수를 넘길수있습니다.
http://common-lisp.net/project/cffi/manual/html_node/defcallback.html#defcallback

그리고 common lisp 구현체중에 임베딩이 가능한 구현체도 있습니다.
덩치가 커서 달가운놈은 아니지만..
http://ecls.sourceforge.net/

물론 임베딩용도라면 scheme 쪽이 더 맞겠지만요..
tinyscheme 등.

dll 을 뽑아주는 구현체도 있습니다. 개발이 계속진행중인지는 모르겠지만 상용 리습입니다.
http://www.cormanlisp.com/features.html

M.W.Park의 이미지

Erlang도 한번 보세요.
제한적 기능을 붙이긴 했지만, 오라클 C 인터페이스(OCI 였던가?)를 erlang과 연동하는 모듈을 이틀정도만에 만든 적이 있습니다.

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

Ooryll Qrygg의 이미지

제 경우 리습을 좋아하는 것은 전적으로 lambda operator 때문이며, 그 이유는 다음과 같은 'Dictionary of Logic as applied in the study of language'의 Abstraction operator 항목 (p. 2)의 설명으로 대신할 수 있지 않을까 생각합니다.

4. The abstraction operator can be treated as a special case of a more general operator which operates on any expressions whatever, not only predicate expressions. This device has been called the lambda-operator by A. Church.
The forerunner of the idea was again Frege (1893) who applied his 'smooth breathing operator' not only to predicate expression but also to terms expressing functions, e.g., 'x^2-x'. The value range, German Wertlauf, of this function is the set denoted, in Frege's notation, by 'a(a^2-a); provided x range over natural numbers, it is the infinite set {0, 2, 6, 12, ...}. That process of forming a function is nowadays called the functional abstraction.
Hence a lambda-expression, i.e., an expression of the form (lambda x)(...x...) is either a predicate expression or a function expression. Both are defined by the schema: (lambda x) (...x...)a iff ...a...;
that is, the definiendum is equivalent with what results from substituting 'a' for 'x' in the operand, i.e. in the expression that is within the scope of the operator.
What is called the lambda-operator is the part of the lambda-expression consisting of the Greek letter lambda and a variable, enclosed within parenthesis.

imyejin의 이미지

lambda 오퍼레이터를 좋아하신다면 리습 말고 다른 함수형 언어들도 좋아하시겠군요.

C와 김정일 글타래에서도 이미 언급했습니다만, 요즘에는 뜬다 하는 언어들은 전부 다 람다를 어떻게든 다 집어넣고 있어서 보통 함수형 언어라고 부르지 않는 언어에서도 사용할 수 있긴 합니다. 파이썬에도 람다함수가 있고 심지어 C#에도 delegate 라는 녀석이 있죠. 다만 그러한 장점을 살리는 라이브러리가 아무래도 함수형 언어보다는 적을 것이고 언어 구현에서 꼬리 되돌기 최적화나 A-normal form으로 클로져 변환 등 함수형 언어에서 기본적으로 하는 최적화를 하지 않는 경우가 많기 때문에 함수형 패러다임으로 작성된 코드가 좀 덜 효율적으로 돌아갈 가능성이 있긴 합니다.

임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin

[예진아씨 피카사 웹앨범] 임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin

hongminhee의 이미지

문득 든 생각입니다. 람다 지원하지 않는 언어가 없는 요즘 세상에, 함수형 프로그래밍 언어라고 부를 수 있으려면 표준 라이브러리의 디자인과 사용자 커뮤니티가 람다를 적극적으로 사용해야 한다고 봅니다. 그런 점에서 C#이 아무리 list comprehensions를 가져와 LINQ를 만들고 람다를 추가해도… (이하 생략)

Ooryll Qrygg의 이미지

제목과 같습니다

winner의 이미지

많은 분들의 이야기를 들으면서 많은 것을 배웠습니다. 하지만 더이상 획기적인 관점을 제시하는 글이 나올런지 모르겠네요.

저는 John McCathy에게 묻고 싶습니다. Python이나 Ruby를 써서 programming을 즐겨보셨냐고요. 안 써봤으면 말을 마라라고 하는 것은 무례한 것일까요? 그런게 아니었다면 John McCathy의 그 질문은 그냥 개그였다는 생각도 듭니다.

많은 발명이 그렇듯, 발명은 발명이 아니라 발견이었다라고도 합니다. Lisp의 발명도 그런 관점이 있는 것으로 압니다. Lisp이 현재에 와서 궁극의 언어로 인식되도록 John McCathy가 계획을 했을 거라고 생각하지는 않습니다. Lisp과 Turing machine에 대해서 둘다 통달하신 분이 둘은 동일한 것이다라고 이야기하는 것도 이해될만 합니다. 왜냐하면 그만큼 고전적인 programming 언어와 computer architecture니까요. Turing machine을 온전히 이해하는 분은 computer가 무엇을 어디까지 할 수 있는지 이해하지만 현재 computer의 CPU와 architecture를 이야기할 때 Turing machine 관점에서 이야기하는 경우는 거의 없죠. Lisp 역시 Lisp을 통달하신 분은 programming 언어로 무엇을 어디까지 할 수 있는지 이야기할 수 있습니다만 Lisp은 주류언어가 아닙니다.

많은 Lisp 해커들이 존경받습니다만 사실 오래되고 성공한 programmer들 중에 Lisp을 많은 언어 속에서 선택해서 통달했는지도 조금 의문입니다. 그 당시에는 Lisp을 쓸 수 밖에 없었을런지도 모릅니다.

많은 뛰어난 programmer들은 한번씩 다 Lisp을 이야기하곤 합니다. Bjarne Stroustrup도 그의 책 "The C++ programing language"에서 메모리 자동관리가 현재의 C++가 앞으로 해야될 사안일 수 있다고 이야기하면서 생각해보고 있는 기법 중 하나로 Lisp 방식을 이야기합니다. Herb Sutter도 C++에 관한 그의 책에서 type과 관련되어 Lisp을 언급하고는 합니다.
gcc와 Emacs의 창시자 RMS는 C와 Lisp을 둘다 할 수 있는 유명한 해커였죠.
Peter Norvig, Matz도 마찬가지입니다.
Java 세계의 저 높은 것에서 Guy Steele Jr. 역시 유명한 Lisp 해커입니다.

다들 Lisp으로 유명하거나 Lisp을 아는 분들이고, Lisp만이 그들의 성공을 이야기할 수 있는 전부는 아닐꺼라고 봅니다.

이 토론을 읽다가 고전 C++의 세계에서 은연 중 강력한 영향력을 발휘했던 James Coplien의 책 "Advanced C++"를 꺼내 봤습니다. 6년 전 책을 사서 마치 SICP 처럼 읽다가 내팽개치기를 여러번 한 책인데 C++의 진화에 대해서 다음과 같은 구절이 있습니다.

"이런 결정시 한 가지 중요하게 고려할 사항이 있다. 바로 '고급 특징에 따른 복잡성을 어디에다 묻어버릴까'다. 복잡성을 컴파일러에 부가하면 사용자를 위한 개발 과정을 단순화시킬 수 있다. 즉 컴파일러의 여러 작업 중에서 메모리 관리, 초기화, 삭제, 타입 변환, I/O와 연계한 일들을 자동으로 처리할 수 있다. 그러나 C++ 진화를 이끄는 원칙 중 하나는 사용자 편의성을 희생하면서까지 컴파일러를 단순하게 만들어서는 안 되며, 반대로 컴파일러에 지나치게 복잡한 작업을 시켜도 갈등에 빠진다는 사실이다. 사용자가 사용할 수 있는 모델을 딱 하나라고 제한하든지('전제군주적' 언어) 아니면 언어 자체가 잡동사니 같은 대안을 표현할 수 있도록 성장시키든지('무정부주의적' 언어) 서로 반대 방향으로 뻗어나가는 양극현상이 벌어진다."

처음 이 책을 샀을 때 마치 SICP를 혐오하는 사람들처럼 C++의 현대적 스타일이 발전하는 지금, 이책은 쓸모없는 책이라고 생각했었습니다. 하지만 동적언어를 조금씩 배워가는 과정에서 다시금 이 책에 도전하고 싶은 욕구를 가지게 됩니다.

이 책에서는 또한 다음과 같은 구절도 있습니다.

"이 책은 결코 대규모 시스템에서 C++를 사용하는 방법에 관한 마지막 복음서가 아니다. 실험하고 탐구하고 수립한 후에는 주저하지 말고 이 책을 집어 던져라!"

Lisp이 집어 던져버려진 것이 Lisp의 실패가 아니라 Lisp의 성공일 때도 많다고 봅니다.

chanwooyoo의 이미지

많은 분들이 리습을 '이론적으로 좋은 언어'라고 막연히 생각하시는 것 같습니다. 저는 파이썬과 루비를 접한 뒤에 리습을 접하게 된 케이스입니다. 소위 '아무도 안 쓰는' 비주류 언어인 리습을 공부하는 건 시간낭비가 아닐까 하는 두려움도 있었고, 그냥 파이썬이나 루비를 갖고 노는 게 내 장래에 더 도움이 되지 않을까 하는 생각도 많이 했습니다. 하지만 아무리 노력해도 리습을 벗어날 수가 없었습니다. 그 이유는 언어란 자신의 생각을 표현하기 위한 '도구'인데 리습을 제외한 다른 언어에서는 어떤 개념들은 표현하는 데 지나칠 정도로 많은 노력이 들거나 아니면 표현하기가 거의 불가능했기 때문입니다. 많은 분들이 말씀하시는 것처럼 '이론상으로는 리습으로 어떤 개념이든 표현할 수 있겠지'라는 게 아니라, 리습으로는 1)다른 언어로 표현할 수 없는 것을 표현할 수 있거나 2)다른 언어로 표현할 수 있는 것을 훨씬 적은 노력으로 표현할 수 있었습니다.(Perl 유저분들 죄송합니다. 좀 빌려왔습니다. ^^;)

제가 예전에 Clojure라는 리습으로 짠 간단한 객체 지향 시스템이 있습니다.(참조: http://lisp.tistory.com/entry/Clojure로-짠-Object-Oriented-System) 클래스를 선언할 수 있고, 객체를 만들에 메써드를 호출할 수 있고(정확히는 메시지를 보낼 수 있고), 상속을 지원하고, 메써드 내에서 self로 객체 자신을 참조할 수 있는, 간단한 시스템이었습니다. 주석을 제외한 전체 소스 코드가 90줄이 안되고, 짜는 데는 하루가 안 걸렸습니다. 연구실에서 다른 언어를 사용하는 분들께 같은 일을 한 번 해보라고 제안했을 때 ^^;;; 대부분 자신이 사용하는 언어로는 제가 들인 노력보다 일이 많을 것 같고 귀찮기 때문에 응하는 사람이 없었습니다. 아니면 이미 객체 지향 언어를 사용하고 있는데 어떻게 객체 지향 시스템을 만드냐고 반문하시는 분이 계셨습니다. 글쎄요 예를 들어 루비라면 class 대신 my_class, < 대신 my_< 와 같은 식으로 자신만의 객체 지향 시스템을 만들어 볼 수 있겠죠. 대신 기존 class 키워드를 그대로 이용하는 게 아니라 시스템의 구현은 짜야겠죠. 흥미롭거나 내키시는 분들만 한 번 짜 보시고 각자의 블로그에 올리신 후 결과를 서로 비교해 봐도 재밌을 것 같아요.

저는 실제적인 이유 때문에 리습을 버릴 수가 없었습니다. 언어가 프로그래머의 생각을 표현하는 도구라면, 왜 어떤 생각은 표현할 수 조차 없는 '불완전한' 도구를 사용해야 하는 걸까요? 왜 스스로를 제한하고, 한계 속에 갇히려 할까요? 기계어 얘기를 하시며 기계어나 리습이나 이론적으로는 뭐든지 가능하겠지 라고 말씀하실 분도 계실지 모르지만, 전 이론적으로가 아니라 실제로 해 보니 무엇인가를 표현하기가 너무 쉽고 자유로웠다라는 얘기를 하고 싶습니다.

--------------
lisp.tistory.com


--------------
lisp.tistory.com

winner의 이미지

만일 kernel을 Lisp으로 작성한다면 어떨까요? Linus Torvalds가 뭐라고 할까요?

저는 Lisp의 유용성을 부정하지는 않습니다. 하지만 Lisp이 유용한만큼 위험하다는 것을 인지하지 않는다면 Lisp을 활용할 수 없다고 생각합니다.
표현의 경제성 역시 마찬가지입니다. 전문가들은 자신의 생각을 간결하게 표현하길 원합니다. 하지만 전문가들의 간결한 표현에는 전문가들이 고민하고 고생했던 수많은 시간을 묻어버리는 것이지요.
그것은 분명 유용합니다만 위험할 수 있습니다.

chanwooyoo의 이미지

80년대까지만 해도 리습으로 짠 OS도 있었고 리습으로 우주선에 들어가는 코드도 짜서 날리고 했답니다. Prcatical Common Lisp에서 따 온 다음 글을 한 번 보시죠. 우주선에 들어가 있는 리습 코드를 리습 REPL(파이썬이나 루비의 interactive shell같은 거라고 생각하시면 됩니다.)을 통해 디버깅했다는 이야기죠.. 인공지능 붐의 몰락과 함께 이제는 모두 사라져버린 이야기지만..

"An even more impressive instance of remote debugging occurred on NASA's 1998 Deep Space 1 mission. A half year after the space craft launched, a bit of Lisp code was going to control the spacecraft for two days while conducting a sequence of experiments. Unfortunately, a subtle race condition in the code had escaped detection during ground testing and was already in space. When the bug manifested in the wild--100 million miles away from Earth--the team was able to diagnose and fix the running code, allowing the experiments to complete.14 One of the programmers described it as follows:

Debugging a program running on a $100M piece of hardware that is 100 million miles away is an interesting experience. Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem."

--------------
lisp.tistory.com


--------------
lisp.tistory.com

winner의 이미지

준비하면서 말이예요. ^_^.

저도 그이야기는 들었습니다. Lisp Machine과 우주선의 REPL. ^_^.

죠커의 이미지

데이터와 코드를 같은 관점에서 바라보는 것은 그렇지 않은 언어에 비해 더 유연하게 만들어줍니다. 새로운 패러다임이 있는 것이 아니라면 리습만큼 유연하는 것은 쉬운 일이 아닙니다. 새로운 패러다임에 의해 유연한 언어가 나왔다면 그 패러다임에 대해 소개를 하는 섹션이 프레젠테이션에 마련되었겠죠. 루비나 파이썬이 리습의 대안이 존 맥카시가 아니라고 판단하기에는 충분한 것 같습니다.

- 죠커's blog / HanIRC:#CN

esrevinu의 이미지

Quote:
Specifically he identified Common Lisp's lack of pattern-matching, inconsistency with respect to lambda calculus theory (partial applications being missing), procedural contamination and lack of static typing.

Qi (氣의 한어병음인 것 같습니다. 아마도 '치'라고 발음)라는 언어의 wikipedia 페이지( http://en.wikipedia.org/wiki/Qi_%28programming_language%29 )의 일부인데요, Lisp의 부족한 점이 static typing 이외도, pattern matching, partial applications 라고 적혀 있네요.
Haskell 공부하고 있었는데 Lisp 관련글이 올라오길래 구글에 lisp vs haskell 로 검색을 했더니 Qi에 대한 언급이 있더군요.
전 토론할 실력이 안 되니까 이것만 올리고 빠지겠습니다. Lisp도 공부해 보려고 합니다. 취미로...

M.W.Park의 이미지

이런 글타래(lisp, functional 관련)가 열릴 때마다 예전에는 비교적 많은 글을 달았었는데요.
이번에 문득 드는 생각은 실제로 사용하는 사람들인지, 공부하는 사람들인지, 그냥 호기심을 가진 사람들인지 궁금해졌습니다.

진지하게 사용하시는 사람은 손 들어주세요!!
(제 경우에는 Lisp, Erlang을 합쳐서 LOC가 최소 10000 정도는 됩니다. 물론 test code는 제외)

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

johan의 이미지

100회 기념(?) - CL LOC 500K 이상 - Macro expansion 제외(포함시 x10 이상), 테스트 코드 포함.

chanwooyoo의 이미지

제품을 만드는 경우만 해당되는 것인지 아니면 연구 목적을 위해 자신이 원하는 도구로 활용하는 것도 포함하는 것인지 잘 모르겠습니다.

그리고 해당 언어에 대해 경험해 본 정도를 파악하기 위해, 보통 LOC를 참고하는 것 같은데 이 경우에 왜 작성해 본 코드만 따지는지는 잘 모르겠습니다. Code Reading이란 책에서도 얘기하는 거지만, 어느 분야든 좋은 책을 쓰기 위해서는 먼저 다른 클래식들을 읽고 분석해 보는 게 필요합니다. 프로그래밍도 마찬가지인 것 같습니다. 회사 면접에서 어떤 코드를 읽고 분석해봤니? 라고 묻기보다 몇 줄이나 짜 봤어? 라고 묻는 것은 기본 문법만 배우고 나면 무턱대고 무엇이든 짜 보게 하는 현재 프로그래밍 교육의 상태를 보여주는 것 같습니다. 솔직히, 자신이 원하는 코드를 짜는 것 보다 남이 짠 코드를 분석하는 게 배 이상 어려운 것 같다는 느낌입니다.

현재 대학원에서 공부중이고, 개인 프로젝트나 연구에 필요할 때 리습이나 루비를 사용하는 편입니다. 웹 관련 공부를 할 때 Weblocks라는 리습 웹 프레임워크를 분석해 본 적이 있구요, metatilities, hunchentoot, contextL, aspectL 등의 코드를 읽어봤습니다. 논문 때문에 구현한 것이나 재미로 짜 본 것들을 라인 수 세는 스크립트로 돌려보니 4000 라인 조금 못 미치네요.

--------------
lisp.tistory.com


--------------
lisp.tistory.com

johan의 이미지

LOC에 대해 너무 거부감을 갖을 필요는 없습니다. 화가에게 그림 여지껏 몇점 그려 보았나 묻는 것과 비슷하다고 봅니다(잘 그렸냐 못그렸냐를 묻는 것이 아닙니다). 위에 500K라 했지만, 그중 지금도 남아있는 것을 얼마 안됩니다. 코드를 읽는 것은 기본이죠. 프로그래머라고 하면 어떤 것을 얼마나 많이 해보았는가 묻는 것도 한가지 방법입니다. 코드를 썼다가 읽어보고 생각하고 삭제하고 다시 쓰고 그런 일들이 프로그래밍 특히 유지보수 입니다. 대학원생이라고 하셨으니 여유 있으시리라 생각합니다(적어도 직장인 보다는) 열심히 하세요 - 간혹 학생일 때 열심히 하지 않은 일이 후회됩니다.

semmal의 이미지

이 때쯤에는 kldp에 들어오기 힘들어서 이런 글이 있는지도 몰랐네요.
댓글을 쭈욱 읽다보니 이미 알고있던 것도 되새기고, 가물가물하던게 생각나고, 모르던걸 알게되어서 참 기쁩니다.
그런데 리습에 대해서 대화를 하는 것을 지켜보니 왠지 우리글과 우리말에 대해서 토론하는 기분을 느낍니다.
그렇게 생각하고 나니 정말 비슷한 것 같습니다.
기본적인 알파벳이 너무 쉬운 한글과 기본적인 문법이 너무 단순한 Lisp.
다양한 외래어를 표현할 수 있지만 오히려 다양한 표현으로 인해 말을 배우는 외국인에게 혼란을 가중시키는 우리말과, 다양한 패러다임을 포용할 수 있지만 복잡한 라이브러리 스펙으로 인해 오히려 질리게 만들어버리는 CommonLisp.
우리글이 우수한지 잘 알지만 우리조차도 잘쓰기 힘든 우리말, Lisp이 뛰어나다는 걸 알지만 알면서도 쓰기 힘든 Common Lisp.
그럼 세종대왕과 John McCathy가 비슷한 격이 되나요?
어쨌든, chanwooyoo님이 좋은 글을 시작해주셔서 고맙습니다.
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

익명 사용자의 이미지

리습, "이맥스"에서만 살아 숨쉬고 있군요.

익명 사용자의 이미지

2011년 최근에 리습 LISP 으로 진행되고 있는 주목할만한 "프로젝트"는 무엇이 있을까요? (AutoLISP 같은 류의 '좀비 리습'은 제외하고...)

익명 사용자의 이미지

하루 정도 써봤는데 할 만한데요?
땡기네요 ㅎㅎ

익명 사용자의 이미지

저도 하루 써봤는데.. 별로...
개인적으로 클로저는 지저분해 보임.

페이지