Emacs 리스프

Emacs Lisp
Emacs 리스프
EmacsIcon.svg
Emacs 로고
패러다임기능성, 메타, 반사성
가족리스프
설계자리처드 스톨먼
가이 L. 스틸 주니어
개발자GNU 프로젝트
처음 등장한1985년; 37년 전 (1985년)
안정된 릴리스
2022년 4월 28일 / 4월 4일; 4개월 전(2022-04-04)
타이핑 분야다이내믹하고 강력함
범위동적, 옵션 어휘
플랫폼에맥스
OS크로스 플랫폼
면허증.GPLv3
파일 이름 확장자.el, .elc, .eln
웹 사이트www.gnu.org/software/emacs
영향을 받다
일반 리스프, Maclisp

Emacs Lisp는 Emacs(GNU Emacs 및 XEmacs가장 일반적으로 관련된 텍스트 에디터 패밀리)에서 스크립팅 언어로 사용되는 리스프 프로그래밍 언어의 방언입니다.이 명령어는 Emacs에 내장된 대부분의 편집 기능을 구현하기 위해 사용되며, 나머지는 Lisp 인터프리터와 마찬가지로 C로 기술됩니다.Emacs Lisp는 Elisp라고도 불리지만, 그 이름을 [1]가진 더 오래되고 관련이 없는 Lisp 방언도 있다.

Emacs 사용자는 일반적으로 Emacs Lisp 코드를 작성하여 Emacs를 커스터마이즈 및 확장합니다.다른 옵션으로는 버전 20부터 GNU Emacs에 있는 커스터마이즈 기능이 있습니다.Emacs Lisp로 작성된 Customize에는 사용자가 실행 중인 Emacs 세션에서 옵션을 설정하고 그 효과를 미리 볼 수 있는 일련의 기본 설정 페이지가 있습니다.사용자가 변경 내용을 저장하면 Customize는 필요한 Emacs Lisp 코드를 사용자 설정 파일에 기록하기만 하면 됩니다.이 파일은 사용자 자신의 파일을 변경할 가능성을 피하기 위해 Customize만 사용하는 특수 파일로 설정할 수 있습니다.

Emacs Lisp는 배치모드로 Emacs를 호출함으로써 Unix Bourne 또는 Perl과 마찬가지로 스크립트 언어로서 기능할 수도 있습니다.이와 같이 명령행 또는 실행 파일을 통해 호출할 수 있으며, 버퍼 및 이동 명령과 같은 편집 기능은 일반 모드와 동일하게 프로그램에서 사용할 수 있습니다.Emacs 를 배치 모드로 기동했을 때는, 유저 인터페이스는 표시되지 않습니다.이 인터페이스는 전달된 스크립트를 실행하고 종료하기만 하면 스크립트의 출력이 표시됩니다.

다른 리스프 방언과 비교

Emacs Lisp는 Maclisp와 가장 가까운 관계이며, 나중에 Common [2]Lisp의 영향을 받습니다.필수 및 기능 프로그래밍 방법을 지원합니다.Richard Stallman은 Emacs(원래 확장 언어로 Text Editor and Corrector(TECO)를 사용)를 다시 쓰는 확장 언어로 Lisp를 선택했습니다.이것은 함수를 데이터로 취급하는 기능을 포함한 강력한 기능 때문입니다.Common Lisp 표준은 아직 공식화되지 않았지만 Stallman이 GNU Emacs로 Gosling Emacs를 다시 쓸 때 스킴이 존재했다.그는 워크스테이션에서의 성능이 상대적으로 낮기 때문에 사용하지 않기로 선택했고(Emacs의 전통적인 집이었던 미니컴퓨터와 달리), 그는 보다 쉽게 [3]최적화될 수 있는 사투리를 개발하기를 원했다.

Emacs에서 사용되는 리스프 방언은 애플리케이션 프로그래밍에 사용되는 보다 현대적인 공통 리스프 스킴 방언과는 크게 다릅니다.Emacs Lisp의 두드러진 특징은 기본적으로 어휘적 스코프가 아닌 동적 스코프를 사용하는 것입니다.즉, 함수가 호출된 범위에서 로컬 변수를 참조할 수 있지만 정의된 범위에서는 참조할 수 없습니다.최근에는 아래에 설명된 이유로 어휘 범위 지정을 사용하도록 코드를 업데이트하려는 노력이 계속되고 있습니다.

1955 1960 1965 1970 1975 1980 1985 1990 1995 2000 2005 2010 2015 2020
LISP 1, 1.5, LISP 2(abandoned)
마클리스프
인터리스크
MDL
리스프 기계 리스프
스킴 R5RS R6RS R7RS 소형
없음
ZIL(Zork 구현 언어)
프란츠 리스프
일반적인 리스프
르 리스프
MIT 스킴
T
체즈 스킴
Emacs 리스프
자동 LISP
피코리스프
EuLisp
ISLISP
오픈리스프
PLT 방식 라켓
GNU Guile
비주얼 LISP
클로쥬르
LFE
하이

Emacs Lisp의 이면에 있는 논리를 이해하기 위해서는 범용 프로그래밍 언어를 구현하는 것보다 범용 텍스트에디터를 만드는 데 특화된 데이터 구조와 기능을 제공하는 데 중점을 두어야 합니다.예를 들어 Emacs Lisp는 파일을 한 번에 한 줄씩 쉽게 읽을 수 없습니다.파일 전체를 Emacs 버퍼로 읽어야 합니다.단, Emacs Lisp는 모드에 의해 정의된 문장, 단락 또는 상위 구문 수준에서 버퍼 텍스트를 탐색하고 수정하기 위한 많은 기능을 제공합니다.

다음으로 Emacs Lisp로 기술된Emacs 확장의 간단한 예를 나타냅니다.Emacs에서는 편집 영역을 window라고 불리는 개별 영역으로 분할할 수 있습니다.각 영역에는 다른 버퍼가 표시됩니다.버퍼는 텍스트 문서에 저장할 수 있는 Emacs의 메모리에 로드된 텍스트 영역입니다.

사용자는 기본 키 바인딩을 눌러 새 창을 열 수 있습니다.그러면 Emacs Lisp 기능이 실행됩니다.split-window-below보통 새 창이 뜨면 이전 창과 동일한 버퍼가 표시됩니다.다음으로 사용 가능한 버퍼를 표시하도록 하겠습니다.이를 위해 사용자는 다음 Emacs Lisp 코드를 기존 Emacs Lisp 소스 파일 또는 빈 Emacs 버퍼에 씁니다.

(삭제하다 my-buffic-func ()   (상호적인)   (스플릿 스플릿 스플릿 스플릿 스플릿 스탭)   (설정값 (다음 번) (다른 사람)))  (글로벌 세트키 (kbd "C-x 2") #'my-buffic-func) 

첫 번째 문장은(defun ...)새로운 기능을 정의합니다.my-split-window-func를 호출합니다.split-window-below(오래된 윈도우 표시 기능)는 새로운 윈도우에 다른 (새로운) 버퍼를 표시하도록 지시합니다.두 번째 문장은(global-set-key ...)는, 키 시퀀스 「C-x 2」를 새로운 기능에 재바인드 합니다.

이는 어드바이스라고 불리는 기능을 사용하여 작성할 수도 있습니다.이를 통해 사용자는 자신의 기능을 정의하는 대신 기존 기능을 중심으로 래퍼를 작성할 수 있습니다.이는 키바인딩을 변경할 필요가 없고 원래 함수가 호출되는 곳이면 어디서나 작동할 수 있을 뿐만 아니라 쓰기 작업도 간단하지만 디버깅이 더 복잡해진다는 단점이 있습니다.이러한 이유로 GNU Emacs의 [4]소스 코드에서는 어드바이스를 사용할 수 없지만 사용자가 원할 경우 어드바이저리 기능을 코드로 사용하여 위의 코드를 다음과 같이 재실장할 수 있습니다.

(어드바이스를 해제하다 스플릿 스플릿 스플릿 스플릿 스플릿 스탭   (끝나고 마이-카메라-크리스라 첫번째 () 작동시키다)   (설정값 (다음 번) (다른 사람))) 

이것은 지시사항입니다.split-window-below사용자가 제공한 코드가 호출될 때마다 나머지 함수를 실행한 후 실행합니다.또, 원래의 기능보다 먼저 실행하도록 어드바이스를 지정하거나(원본을 문자 그대로 랩핑), 어드바이스의 결과에 근거해 원래의 기능을 조건부로 실행하도록 지정할 수 있습니다.

Emacs 24.4가[5] 이를 대체합니다.defadvice와의 메커니즘.advice-add보다 유연하고 [6]심플하다고 알려져 있습니다.위의 조언은 새로운 시스템을 사용하여 다음과 같이 재실장할 수 있습니다.

(삭제하다 다음 번 수신으로 전환 ()   (설정값 (다음 번) (다른 사람)))  (어드바이스 추가 '자신감각' : 전 #'다음 번 수신으로 전환) 

이러한 변경은 코드가 평가되는 즉시 적용됩니다.컨피규레이션파일을 재컴파일, Emacs 를 재기동하거나 재해시 할 필요는 없습니다.코드가 Emacs init 파일에 저장되어 있는 경우, Emacs는 다음에 시작할 때 확장자를 로드합니다.그렇지 않으면 Emacs 재시작 시 변경을 수동으로 재평가해야 합니다.

소스 코드

Emacs Lisp 코드는 파일 시스템플레인텍스트 파일로 저장됩니다.규칙에 따라 파일 이름 서픽스는 " " 입니다..el". 사용자의 init 파일은 예외이며, 종종 다음과 같이 표시됩니다..emacs"는 Emacs Lisp 코드로 평가됩니다.1990년대 중반 이후 Emacs는~/.emacs.el그리고.~/.emacs.d/init.el또한 사용자는 명령줄에 config 파일로 로드할 파일을 지정하거나 config 파일을 로드하지 않음을 명시적으로 지정할 수 있습니다.파일이 로드되면 Emacs 프로그램의 인터프리터 컴포넌트가 함수 및 변수를 읽고 해석하여 메모리에 저장합니다.그런 다음 다른 편집 기능 및 사용자 명령에 사용할 수 있습니다.에디터를 재기동하거나 컨피규레이션파일을 새로고침하지 않고 함수 및 변수를 자유롭게 수정 및 재정의할 수 있습니다.

시간과 메모리 공간을 절약하기 위해 Emacs 기능의 대부분은 필요할 때만 로드됩니다.Emacs와 함께 제공되는 각 옵션 기능 세트는 패키지 또는 라이브러리라고 불리는 Emacs 코드 모음에 의해 구현됩니다.예를 들어 프로그램 소스 코드의 키워드를 강조 표시하는 라이브러리와 테트리스 게임을 플레이하는 라이브러리가 있다.각 라이브러리는 하나 이상의 Emacs Lisp 소스 파일을 사용하여 구현됩니다.라이브러리는 하나 이상의 주요 모드를 정의하여 기능을 활성화하고 제어할 수 있습니다.

Emacs 개발자는 특정 함수를 C로 작성합니다.이들은 기본 함수 또는 하위 함수로도 불리는 기본 요소입니다.기본은 Lisp 코드에서 호출할 수 있지만 C 소스 파일을 편집하고 다시 컴파일해야 수정할 수 있습니다.GNU Emacs에서 프리미티브는 외부 라이브러리로 사용할 수 없습니다.Emacs 실행 파일의 일부입니다.XEmac에서는 운영 체제의 동적 링크 지원을 사용하여 이러한 기본 요소의 런타임 로딩이 가능합니다.함수는 Emacs Lisp에서 달리 사용할 수 없는 외부 데이터 및 라이브러리에 대한 액세스가 필요하거나 C와 Emacs Lisp의 비교 속도가 상당한 차이를 보일 정도로 자주 호출되기 때문에 원시 함수로 작성될 수 있습니다.

단, C 코드의 오류는 세그멘테이션 위반 또는 에디터를 크래시하는 보다 미묘한 버그로 이어지기 쉬우며 Emacs Lisp 가비지 컬렉터와 올바르게 대화하는 C 코드의 기입은 에러 발생 가능성이 높기 때문에 프리미티브로서 실장되는 함수의 수는 최소한으로 억제됩니다.

바이트 코드

바이트 컴파일을 사용하면 Emacs Lisp 코드를 보다 빠르게 실행할 수 있습니다.Emacs에는 Emacs Lisp 소스 파일을 바이트 코드라는 특별한 표현으로 변환할 수 있는 컴파일러가 포함되어 있습니다.Emacs Lisp 바이트 코드 파일에는 파일 이름 접미사가 " " 입니다..elc". 소스 파일에 비해 바이트 코드 파일은 로딩 속도가 빠르고 디스크 공간을 적게 차지하며 로딩 시 메모리 사용량이 적어 실행 속도가 빨라집니다.

바이트 코드는 여전히 원시 코드보다 느리게 실행되지만 바이트 코드로 로드된 함수는 쉽게 수정하고 다시 로드할 수 있습니다.또한 바이트 코드 파일은 플랫폼에 의존하지 않습니다.Emacs와 함께 배포되는 표준 Emacs Lisp 코드는 바이트 코드로 로드되지만 일치하는 소스 파일도 일반적으로 사용자의 참조용으로 제공됩니다.사용자가 제공한 확장자는 크기가 크지도 않고 계산 부하도 높지 않기 때문에 일반적으로 바이트 컴파일이 되지 않습니다.

언어 기능

특히 "cl-lib" 패키지는 공통 리스프의 상당히 큰 서브셋을 구현합니다.이 패키지는 기존의 Emacs Lisp 함수 정의를 Common Lisp와 유사한 것으로 덮어쓰는 이전 "cl" 패키지를 대체합니다.한편, "cl-lib" 패키지는 Emacs Lisp 스타일의 가이드라인을 보다 밀접하게 따르고 정의되는 각 함수와 매크로 앞에 "cl-"(예:cl-defun내장 이름과 경합하지 않음defuncl 패키지가 로드될 때마다 발생할 수 있는 예기치 않은 동작의 변화를 방지합니다.

Emacs Lisp(다른 일부 Lisp 구현과 달리)는 테일콜 [7]최적화를 하지 않습니다.이것이 없으면 테일 재귀인해 스택오버플로가 발생할 수 있습니다.

apel 라이브러리는 polysylabi 플랫폼브릿지를 사용하여 휴대용 Emacs Lisp 코드 작성을 지원합니다.

Emacs Lisp는 Lisp-2로, 다른 [8]변수에 사용하는 이름공간과는 다른 함수 이름공간이 있음을 의미합니다.

동적 범위 지정에서 어휘 범위 지정까지

MacLisp와 마찬가지로 Emacs Lisp는 동적 스코프를 사용하여 버전 [9]24부터 옵션으로 정적(또는 어휘적)을 제공합니다.파일 로컬 변수를 설정하여 활성화할 수 있습니다.lexical-binding[10][11]옵션이 추가되기 전에lexical-let효과적인 어휘 [12]범위를 제공하기 위해 (현재 폐지된) "cl" 패키지의 매크로를 사용합니다.

동적 스코핑에서는 프로그래머가 함수의 범위 내에서 변수를 선언하면 해당 함수 내에서 호출된 서브루틴에 사용할 수 있습니다.원래 이것은 최적화를 의도한 것이었다. 어휘 범위 지정은 여전히 드물었고 성능이 불확실했다."RMS가 emacs lisp를 구현하고 있을 때 왜 동적으로 스코프를 적용했는지를 물었더니 정확한 답변은 어휘 스코프가 너무 [13]비효율적이라는 것이었습니다.동적 범위 지정은 사용자 맞춤에 더 많은 유연성을 제공하기 위한 것이기도 했습니다.그러나 다이내믹 스코핑에는 몇 가지 단점이 있습니다.첫째, 서로 다른 함수에서 변수 간의 의도하지 않은 상호작용으로 인해 큰 프로그램에서 버그가 발생하기 쉽습니다.둘째, 동적 범위 지정에서 변수에 액세스하는 것은 일반적으로 어휘 [14]범위 지정에서보다 느립니다.

레퍼런스

  1. ^ "HEDRICK at RUTGERS (Mngr DEC-20's/Dir LCSR Comp Facility" (1981-12-18). ""information about Common Lisp implementation"". Letter to "rpg at SU-AI, jonl at MIT-AI". Archived from the original on 2016-09-20. Retrieved 2019-07-28. We have some experience in Lisp implementation now, since Elisp (the extended implementation of Rutgers/UCI Lisp) is essentially finished.
  2. ^ GNU Emacs Lisp는 대부분 Maclisp에서 영감을 받았고 Common Lisp에서 영감을 받았습니다.Common Lisp를 알면 많은 유사점을 알 수 있습니다.그러나 GNU Emacs의 메모리 요건을 줄이기 위해 Common Lisp의 많은 기능이 생략되거나 단순화되었습니다.단순화가 너무 심플해서 일반 리스프 사용자는 매우 혼란스러울 수 있습니다.GNU Emacs Lisp가 일반적인 Lisp와 어떻게 다른지 지적하는 경우가 있습니다.– Emacs Lisp 매뉴얼의 "개요"의 "이력" 섹션에서 Emacs Lisp 매뉴얼을 참조해 주십시오.
  3. ^ "그래서 그 운영체제, GNU 운영체제의 개발이 제가 GNU Emacs를 작성하게 된 계기가 되었습니다.이를 통해 가능한 한 최소한의 Lisp 구현을 목표로 했습니다.프로그램의 규모는 엄청난 걱정거리였다.1985년에는 가상 메모리 없이1 메가바이트의 기계를 가지고 있었습니다그들은 GNU Emacs를 사용할 수 있기를 원했다.즉, 프로그램을 가능한 한 작게 유지해야 했습니다." – "My Lisp Experience and the Development of GNU Emacs"에서
  4. ^ "Re: [Emacs-diffs] /srv/bzr/emacs/trunk r111086: gmm-utils.el (gmm-flet". Lists.gnu.org. 2012-12-05. Retrieved 2013-08-18.
  5. ^ "NEWS.24.4".
  6. ^ "Porting old advice".
  7. ^ "Appendix C Porting Common Lisp". Gnu.org. Retrieved 2019-10-28. Lisp programmers will want to note that the current Emacs Lisp compiler does not optimize tail recursion
  8. ^ "Google Groups". groups.google.com.
  9. ^ "Emacs 24.1 released". Lists.gnu.org. Retrieved 2013-08-18.
  10. ^ "Lexical binding". Lists.gnu.org. 2011-04-01. Retrieved 2013-08-18.
  11. ^ "Dynamic Binding Vs Lexical Binding". EmacsWiki. 2013-05-17. Retrieved 2013-08-18.
  12. ^ "Obsolete Lexical Binding". GNU Emacs Common Lisp Emulation. GNU Press. Retrieved 27 May 2021.
  13. ^ "T". People.csail.mit.edu. Retrieved 2013-08-18.
  14. ^ Featherston, Sam; Winkler, Susanne (2009-06-02). Process. Walter de Gruyter. ISBN 978-3-11-021614-1.

외부 링크

  • 공식 웹사이트, GNU 프로젝트