Lisp Language

FrontPage|FindPage|TitleIndex|RecentChanges| UserPreferences P RSS

FrontPagecalmshine LispLanguage


1. 역사

최초의 LispLanguage[http]John McCarthy에 의해 창안되었다. 그는 [http]Lisp의 역사에서 1956년에서 1958년 사이에 주요 설계를 마쳤고, 1958년에서 1962년 사이에 구현 했다고 밝히고 있다.

1991년 CACM 9월호의 Lisp 특집 기사를 인용하면, Lisp은 포트란 다음으로 오래된 프로그래밍 언어지만 프로그래밍 패러다임이 바뀔때마다 새로운 패러다임을 수용하면서 변화해왔고 변화하고 있다고 한다.

Lisp은 지난 과거동안 수많은 dialects로 존재해왔다. Lisp 언어라고 하면 대개의 경우 그런 모든 dialects를 통틀어서 일컫는 집합적 의미로 사용된다. 그 중 일부로 MacLisp, ZetaLisp, Franz Lisp, Portable Standard Lisp, InterLisp, CommonLisp, EuLisp, Scheme, Emacs Lisp, AutoLisp 등등이 있다.

현재는 ANSI의 X3J13 위원회에서 정한 CommonLisp이 사실상의 표준이지만, 유럽에서는 EuLisp과 같은 독자적인 LispLanguage를 표준화하려고 시도한 적도 있다.

2. LispLanguage의 가계(family)

LispLanguage의 탄생이후 수많은 프로그래밍 언어에 영향을 끼쳤다. 최초의 함수형 언어로써 이후의 함수형 언어들에 영향을 끼쳤고, 최초의 GC를 갖춘 언어로써 많은 GC를 갖고 있는 언어에 영향을 미쳤다. 또, 강력한 매크로는 Dylan과 같은 프로그래밍 언어에 영향을 끼치기도 했다.
가장 큰 영향을 주고 받은 언어들로 Lisp의 유전자를 갖고 있다고 볼수 있는 언어들로는 위에서 나열한 많은 dialects들과 더불어 Scheme, Dylan 등이 있다.

최근 RubyOnRails와 같은 것으로 각광 받고 있는 RubyLanguage의 경우에는 제작자가 MatzLisp라고 농담할 정도로 많은 것들을 LispLanguage, CommonLisp에서 차용하였다. -- -- ageldama 2007-01-16 13:06:52

직접적으로 '나는 LispDialect'요 하는 언어보다 현재의 언어들에서 많이 사용되는 부분들의 대부분이 LispLanguage에서 처음 시도된 것들이 많이 있다. (Closure, AutomaticMemoryManagement, ReadEvalPrintLoop, ...) -- -- ageldama 2007-01-16 13:06:52

2007년에 JVM 을 타겟으로 한 ClojureLanguage 라는 새로운 Lisp 방언이 등장했다. 2010년에 들어 새롭게 관심을 받고 있는 Funtional Paradigm 의 인기에 힘입어 실제로 여러 실무 현장에서 쓰이고 있으며, 이것을 도입하는 스타트업도 심심찮게 볼 수 있다 특징으로 Lisp-1 에 Immutable Data 로 동작하여 CommonLisp 과 차이를 보이고 있다. JVM 위에서 구동되고 기존에 존재하던 모든 JavaLanguage 용 자원을 그대로 끌어다 쓸 수 있기 때문에 새로 등장한 Lisp 방언 치고는 빠르게 인기를 얻고 있다.

3. Lisp 프로그래밍 스타일, 혹은 왜 핵커들은 Lisp을 좋아할까?

LispLanguage는 데이터와 함수를 통한 추상화뿐만 아니라 제어와 문법에 대한 추상화도 지원해준다. 특히 문법에 대한 추상화는 다른 언어에서는 거의 볼 수 없는 독특한 것이다.

적지않은 핵커들은 자신들의 생각을 있는 그대로 프로그래밍 언어로 표현하길 좋아한다. 대개의 경우 특정 도메인을 기술할 수 있는 미니 언어를 먼저 만든후 그 언어로 기술하기를 즐긴다. Lisp은 그런 프로그래머의 생각을 자연스럽게 표현할 수 있는 다양한 추상화 방법들을 제공한다. 즉, 추상적인 생각을 구체적으로 표현할 수 있는 가상의 언어를 만들어서 그것으로 자신의 생각을 수정없이 거의 그대로 코드로 작성한후, 가상의 언어와 Lisp 언어 사이의 비어있는 부분의 매꾸어 문제해결을 마치는 것이 대부분의 Lisp 핵커들의 스타일이다.

많은 프로그래밍 언어들은 프로그래머의 생각과 구현을 완전히 별개의 것으로 취급해야 하는데 비해 Lisp을 그것들을 하나로 생각할 수 있게 도와준다.

4. Lisp 환경

Smalltalk와 마찬가지로, Lisp은 개발환경과 프로그래밍 언어가 일치되어 있다. 흔히 Lisp을 인터프리터 언어로 아는데 사실은 그렇지 않다. 대부분의 Lisp 구현은 인터랙티브 환경으로 구성된다. 즉, 인터프리터, 컴파일러, 디버거, 에디터 등이 하나의 통합된 환경아래 존재한다. 개발시에는 주로 인터프리터를 이용하지만 원한다면 언제든 프로그램의 일부만(예를들면 함수 하나)을 컴파일할 수 있다. Lisp 벤더들은 자신의 제품에 의존성있는 환경을 제공하는 것이 보통이지만, Emacs와 ILisp 패키지를 이용하면 특정 벤더에 의존함 없이 동일한 환경을 유지하면서 서로 다른 구현을 사용할 수 있다. 이때문에 많은 Lisper들은 Emacs + ILisp을 선호한다.

see also [http]SLIME.

5. Lisp 매크로, 혹은 프로그래밍 가능한 프로그래밍 언어를 사용하기

많은 사람들이 Lisp을 싫어하는 가장 큰 이유가 괄호, 즉 "(" 과 ")" 때문이다. 그렇지만 Lisp의 진정한 힘은 바로 이 괄호에서 나타난다. 잠깐이라도 Lisp 코드를 본 사람이라면 알수있겠지만, Lisp 코드는 Lisp 데이터와 동일한 괄호 구조를 유지한다. 이것을 이용하면 코드를 데이터로 생각하고 그 데이터를 조작하는 프로그램을 작성할 수 있다. 또, 그런 "코드를 데이터로 생각하고 조작하는" 코드를 다시 데이터로 생각하고 그것을 조작하는 프로그램을 작설할 수도 있다. 초기 AI에 Lisp이 많이 사용되었던 이유중 하나가 이런 MetaCircular한 특성이었으리라고 짐작한다.

Lisp의 매크로는 바로 이런 코드를 생성하는 프로그램을 작성할 때 사용된다. 때때로 다른 프로그래밍 언어에서는 감히 흉내도 내지 못할 매크로가 존재하는데, 그런 코드를 읽었을때의 전율은 말로는 표현을 못한다. LispM이 개인적으로 본 매크로 중 가장 기억이 나는 매크로는 함수를 런타임에 바꿔치기한 후 원하는 코드를 실행시킨 다음, 실행이 끝나면 다시 원래의 함수로 바꿔치기 하는 매크로였다. Lisp 이외의 어떤 프로그래밍 언어에서 이것이 가능할까?
글쎄요. 예로 든 매크로가 어떤 것인지 정확히는 모르겠지만, 대부분의 함수형언어(Scheme, ML Family, Haskell)에서 가능하지 않을까요? Lisp은 결정적으로 Dynamic Scoping을 사용합니다. 누군가 왜 Static Scoping대신 Dynamic Scoping을 했냐고 묻자 John McCarthy는 그냥 그랬다고 했다죠? (별 이유가 없다고 그랬다던가요? _-_) 혹시 그것이 예로 든 매크로와 관련이 있나요? -- Selmo
So you're claiming you can write macro in your favourite programming languages which is equivalent with following CommonLisp code? Then show me your code!
  ;;; +, -, *, and / are system defined functions.
  ;;; my+, my-, my*, and my/ are user defined functions.
  (with-functions-rebound ((+ my+) (- my-) (* my*) (/ my/))
     (+ 1 (* 2 3) (/ 4 5)))
  
Dynamic variables are useful things when you know how to use. CommonLisp supports both static and dynamic scope. Sometimes with dynamic variables, Lispers write context establishing macros(and they are useful when you write multi-thread code). --LispM

예로 든 코드가 DynamicScoping 을 보여주는 건가요? 아무로가 보기엔 LexicalScoping(StaticScoping)과 다를게 없어보입니다.위 코드를 Scheme의 LexicalScoping으로 다시 쓰면 아래와 같은데 user defined functions으로 적용한 값이 나옵니다.
   (let ((+ my+) (- my-) (* my*) (/ my/))
       (+ 1 (* 2 3) (/ 4 5)))
   
예로 든 코드는 DynamicScoping을 보여주는 것이 아닙니다. Scheme은 하나의 namespace만 존재하기 때문에 위와 같이 할 수 있습니다. 위의 예를 들때 Scheme에 대해 언급한다는 것을 잊고 안한 것이 실수군요. Scheme은 (논쟁의 여지가 많은) Lisp의 일종으로, CommonLisp과 유사한 매크로(define-syntax)를 갖고 있습니다. 위에서 나온 let을 매크로라고 가정하면 Scheme에서는 다음과 같이 expand 되겠죠.
     ((lambda (+ - * /)
        (+ 1 (* 2 3) (/ 4 5)))
       my+ my- my* my/)
     
제 의도는 함수형 언어라고 해서 모두 그런 매크로가 가능한 것은 아니라는 것을 보여주려고 했습니다.

DynamicScoping을 쓰려면 let 대신 fluid-let을 쓰면 되는데 위의 코드는 굳이 fluid-let을 쓸 필요가 없어보입니다.
어떤 Scheme implementation인지 궁금하군요. 제가 생각하는 Scheme의 문제점 중 하나가 바로 이런 것입니다. 최소한 R4RS 당시에는 실제 프로그래밍 하기에는 부족한 것이 많았습니다. 하지만 아직도 프로그래밍 배울 때는 Scheme이 좋다고 생각합니다. 특히 The Little Lisper(후에 The Little Schemer와 The Seasoned Schemer로 확장된)는 마치 퍼즐을 푸는 것 같아 재미있었던 기억이 납니다.
fluid-let은 한번도 써본적은 없었는데 서핑중에 그러한 syntax가 있다는걸 알았습니다.이를 구현한 Scheme으로는 PLT Scheme,MIT Scheme,STk등이 있습니다.그리고 [http]SRFI에서 15번항목으로 Syntax for dynamic scoping 가 있는데 이곳에서 fluid-let의 구현에 관한 논의가 있었으나 2000년3월10일자로 withdrawn됐습니다. Discussion Archive을 대충보니 의견일치가 이루어지지 않았고 결국 withdrawn 된걸 보면 Scheme의 보수적인 면을 보여주는 것 같네요.
DynamicScoping에 관한 문장 From [http]An Introduction to Scheme and its Implementation
   This(Dynamic Scope) led to very inscrutable bugs, because a procedure would work sometimes, and not others, 
   depending on the names of variables bound in other procedures.
      
   Dynamic scoping is generally considered to have been a big mistake, and was fixed in recent versions of Lisp, 
   such as Common Lisp,which were influenced by Scheme.
   
이상하군요. 그렇다면 위에서 언급한 fluid-let을 왜 제공할까요? :) 논쟁의 여지가 많은의 일부가 바로 이것 입니다. Scheme은 정치적으로 매우 보수적인 입장을 유지하면서 발전하고 있는 프로그래밍 언어입니다. 대부분의 Scheme과 CommonLisp사이에 문제점들은 정치적인 것들입니다. 제가 쓴 원래 글을 잘 읽어보면 어떻게 사용하는지 안다면 유용한 것이라고 했습니다. 칼을 사용하는 사람이 그 사용법을 몰라서 제 살을 베었다고 칼을 탓할 수는 없습니다. 다른 예로 CommonLisp의 CLOS는 다양한 method combination을 제공합니다. Method combination에 대해 잘 이해하지 못하고 프로그래밍 한다면 틀림없이 버그가 생길 것입니다. 또 다른 예로 CommonLisp은 MOP을 이용해서 어느정도(일부가 완전 표준이 아니기 때문에) MetaLevelProgramming을 할 수 있습니다. MOP에 대해 제대로 이해하지 못하면 역시 많은 고생을 하게 될것입니다. Scheme과 CommonLisp은 서로 많은 영향을 주고 받았지만, 특히 CommonLisp이 Scheme에 비해 좀더 적극적으로 좋은 생각들을 받아들였습니다. 위의 글은 정확하지 않은데, 그 이유은 CommonLisp이 Dynamic scoping을 버리지 않고 대신 Static scoping을 받아들였기 때문입니다.
Scheme에 많은 관심을 갖고 사용하다가 직업적으로 학계가 아닌 업계에 종사하며 프로그래밍 하게 된다면 결국 CommonLisp이 Java나 C++로 프로그래밍 하는 것보다 당연히 Lispy하고 Scheme보다는 실세계에서 경쟁력 있는 프로그램을 작성할 수 있습니다. Scheme의 문제점 중 하나는 아직까지 상업적으로 팔수있는 물건이라고 할만한 것이 없다는 점입니다. 4-5년 전쯤에는 Chez Scheme이 가장 가까운 구현이었음에도 불구하고 팔수있는 물건은 아니었습니다. --LispM

꼭 저 인용문이 정확하지 않다고 할 수는 없을 것 같습니다. 뭐가 fix 되었냐는 게 문제인데, dynamic scoping 을 없앤 것이 fix 가 아니고 정확히는 dynamic scoping 이 default 였던 것을 static scoping 이 default 가 되도록 fix 했다는 것 아닐까요? 그리고 커먼 리습의 표준화 과정에서 아예 static scoping 만을 채택한 스킴의 영향을 받았다는 점도 사실이고요. --서상현
보는 시각 차이겠죠. 왜 그렇게 big mistake이면 CommonLisp에서 아예 제거하지 않았겠습니까? 또 왜 Scheme을 쓰는 누군가는 fluid-let같은 것을 원하고 몇몇 영향력있는 구현에서 왜 그것을 지원해서 big mistake를 자초할까요? :) CommonLisp이나 Scheme 두 프로그래밍 언어는 다른 프로그래밍 언어와는 달리 일찍부터 여러 권위있는 전문가들이 표준화하기 시작한 프로그래밍 언어입니다. Scheme은 매우 보수적으로 발전하기 때문에 실수를 거의 하지 않았습니다만, 다른 한편으로는 실용성이 떨어지는 문제점을 안게 되었습니다(이것이야 말로 big mistake아닐까요?). CommonLisp은 분명 실수도 했지만 그런 실수들을 만회할 수 있는 더 나은 확장을 꾀했고 현재까지는 Scheme보다 실용적인 면에서 더 나은 위치에 존재합니다. 이것은 표준화에 각각 참여한 전문가들이 누구였는가 살펴보아도 알수있는데, Scheme의 경우 학계에 있는 사람들이 주축이 된 반면 CommonLisp의 경우 업계에 있는 사람들이 주축이되어 설계하고 발전시켰습니다. 물론 두집단을 오갔던 Guy Steele Jr., Kent Pitman같은 사람도 있었으며, 당연히 CommonLisp과 Scheme은 많은 영향을 서로 주고 받았습니다. 이렇게 영향을 서로 끼친것은 이미 위에서 밝혔듯이, 부정할수 없는, 사실입니다. --LispM

꼭 트집을 잡으려는 건 아니지만, 스킴이 커먼 리습보다 약간 표준화가 앞섰기 때문에, 선후 관계상 커먼 리습이 스킴을 참고할 수는 있었어도 그 역은 아니라고 생각합니다. (라고 쓰고 보니 너무 센 발언이군요. 고칠 말이 딱히 생각나지 않으니 패스.) --서상현
하하 사실은 그 반대라고 생각합니다. Scheme은 실용적이 되기 위해서는 이미 CommonLisp에는 있는 여러 표준들을 참고하여 (쉽지는 않겠지만) 보다 더 나은 것을 만들어내야 합니다. 대충 손꼽아 보면: OOP, stream, 타입에 따른 컴파일 최적화, package, hashtable, 더 풍부한 control structures, 개발환경에 대한 최소한의 표준 등이 생각나는 군요. 갈길은 먼데 더 나은 것 아니면 별 가치를 못느끼는 듯한 Scheme 표준 위원회는 급할 것 없이 천천히 움직이는 듯 합니다. 어떤 사람들이 보면 당연한 것에 너무 시간을 낭비한다는 생각이 들만큼. --LispM
저는 반대되는 사례를 알고 있습니다. C언어에서는 C++의 키워드를 받아들이는데 다른 의미로서 받아들이는 경우가 많습니다. 그래도 C++의 영향이 없었다면 받아들여지지 않았겠지요. 그 역의 경우도 충분히 가능하다고 봅니다. --씨엔

6. Lisp 신화

  • Lisp은 느리다
    • CommonLisp의 상용구현이나 Sbcl과 같은 오픈소스구현은 NativeCodeCompiler가 통합되어 있다. 사용자가 정의한 함수가 자동적으로 실제기계코드로 컴파일되어 실행됩니다. 또한 함수를 정의할때 추가적인 옵션들을 추가하여 결과코드를 생성할 때 최적화할 수 있도록 도울 수 있습니다. 예전의 실험적인 리습구현들이 느렸지만, 현재의 실용적인 구현들은 훨씬 쉽고 빠르게 기계코드를 생성할 수 있습니다. -- ageldama 2007-01-16 13:01:13

  • Lisp은 괄호가 너무 많아서 문제이다
    • Lisp은 괄호가 너무 많아서 좋습니다. ;-) Lisp에 익숙해지고 그 원리를 알아간다면 괄호가 멍청해 보이지 않게 됩니다. 제대로 LispProgramming을 한다면 EmacsSlime과 같은 StateOfArtInteratedDevelopmentEnvironment을 사용하면 괄호가 문제가 되지 않습니다. ;-) -- ageldama 2007-01-16 13:01:13

  • Lisp은 언어 크기가 너무 크다.
    • CommonLisp의 경우 그 Specification이 방대해 보이지만, 실제로 CppLangaugeJavaLanguage의 Specification과 비교해보면 그렇게 크지 않습니다. 또한, 그 자체로 컴파일러, 디버거 등의 다른 부분과 융합되어 있다는 점을 생각하면 그렇게 방대하지 않습니다. 또한 Scheme과 같은 것을 생각하면 절대 크기가 크지 않습니다.(Scheme은 정말 작업 언어에 속합니다.) -- ageldama 2007-01-16 13:01:13

  • Macro 는 궁극의 프로그래밍 도구다
    • Macro 가 강력한 MetaProgramming 도구인 것은 맞으나, 잘못 쓰면 오히려 독이 될 수 있다. 공동으로 작업하는데 상대방이 이해하고 쓰기 어려운 Macro 를 남발한다면 안쓰느니 못한 경우가 발생한다. 게다가 Macro 도 잘 만들어야지, 잘못 만들면 성능 저하가 올 수 있다.

      DeleteMe 단순히 신화만 적는게 아니라 실제는 어떻는지 설명해주실분 없으신가요?

7. Lisp Machines

  • Symbolics
  • TI
  • etc

8. 질문과 답

Q: LispLanguage를 처음 접하는 프로그래머에게 추천할 만한 책이 무엇인지요? 위의 paip도 적당한지요?

A: LispM 홈페이지의 LispMCommonLisp 공부 조언을 참고하세요.

Q: 그런데 왜 훌륭한 LispLanguage 책들이 절판되고 있는 걸까요? 점점 다른 언어로 대체돼가는 추세인가요??

A: 사실 이같은 질문에 대한 정답은 아무도 모를 겁니다. 단지 추측만 해야겠죠. 절판되는 이유는 수요가 줄기 때문이겠죠. 다른 언어로 대체돼가는 추세인지 아닌지 역시 알 수 없습니다. LispLanguage는 (흔히 많은 초보자들이 달려드는) 다른 언어들 보다는 대중적이지 않습니다. 결국, 대부분의 LispLanguage 프로그래머들이 출판된 Lisp책을 구입했다는 확신이 들면 출판사에서는 절판시키겠죠(초보자는 거의 안사본다는 가정하에). 하지만 역설적으로 다른 프로그래밍 언어 책에서는 보기 힘든 양질의 책들이 끊이지 않고 출판되고 있는 것은 아직도 그런 책을 저술하고 읽어 줄 LispLanguage 프로그래머들이 있다는 증거가 아닐까요? 제 경험으로는 대부분의 프로그래밍 언어가 사용되는 어플리케이션들이 별다른 매력없이 그저 시간과 노동만 투입하면 누구나 할 수 있는 것들인 반면, LispLanguage를 사용하는 대부분의 어플리케이션들이 도전적이며 프로그래머라면 한번쯤 경험해보고 싶어하는 일들입니다. 일단, 상업적인 LispLanguage 프로그래밍 경력이 있으면 원한다면 어렵지않게 (재미있고 흥미진진한!) 일자리를 얻을 가능성이 큽니다. --LispM

Q: 상업적인 LispLanguage 프로젝트들의 예는 어떤 것들이 있나요? --이지수

A: 야후 쇼핑몰이 LispLanguage로 만들어졌습니다. 그리고 얼마 전까지 LispLanguage 코드를 CppLanguage로 변환하는 작업이 진행되었습니다. 이유는 LispLanguage를 이해하는 프로그래머가 극히 희귀하다는 것이었습니다. 거의 완성 됐는데, 최근에 그냥 Lisp을 그대로 사용하겠다는 발표가 있었습니다. EMACS를 알게 되어서라고 합니다. (아마 이 뒷부분은 농담일 것임. 4/1일자 [http]포스트) --김창준
A: See also [http]The Association of Lisp Users


"; if (isset($options[timer])) print $menu.$banner."
".$options[timer]->Write()."
"; else print $menu.$banner."
".$timer; ?> # # ?>