언제 / 왜 progn을 사용해야합니까?


19

progn숙련 된 Emacs 사용자의 구성 파일을 탐색 할 때 상당히 많이 사용되는 것을 보았습니다 . 이 멋진 설명을progn 찾았 지만 실제로 궁금한 점은이 기능을 사용하면 어떤 이점이 있습니까? 예를 들어이 스 니펫 ( Sacha Chua의 구성 에서 가져온)을 보자 .

(use-package undo-tree
  :defer t
  :ensure t
  :diminish undo-tree-mode
  :config
  (progn
    (global-undo-tree-mode)
    (setq undo-tree-visualizer-timestamps t)
    (setq undo-tree-visualizer-diff t)))

위의 구성과 이것 사이에 큰 차이가 있습니까?

(use-package undo-tree
  :defer t
  :ensure t
  :diminish undo-tree-mode
  :config
  (global-undo-tree-mode)
  (setq undo-tree-visualizer-timestamps t)
  (setq undo-tree-visualizer-diff t))

구문이 더 많더라도 첫 번째 예제가 다소 깨끗하다고 ​​생각합니다. 직관은을 사용하여 일종의 성능 향상이있을 수 progn있지만 확실하지 않습니다. 통찰력에 감사드립니다!


7
이 특별한 경우에는 차이가 없습니다 : : config 양식이 없으면 주위 use-package를 감싸 progn십시오. 시도해보십시오 :의 끝에 포인트를 넣고 매크로가 어떻게 확장되는지 확인하기 위해 (use-package ...)호출 M-x pp-macroexpand-last-sexp할 수 있습니다. 이 두 예제에서 동일한 것을 볼 수 있습니다.
glucas dec

답변:


11

progn일반적으로 매크로를 다룰 때 사용됩니다. 일부 매크로 ( use-package마지막으로 확인한 매크로)는 하나의 양식 허용 하며 다른 매크로는 나머지 모든 양식을 소비 합니다 .

progn 전자의 경우에는 일련의 양식을 단일 양식으로 변환하는 데 사용됩니다.

귀하의 예에서 첫 번째는 다음을 사용 progn하므로 1 개의 형식:config있습니다. 두 번째에는 3 가지 형태가 있습니다. 경우 use-package매크로는 1 개 형태의 다음을 기대하고 :config, 그것은 오류가 발생합니다.

progn매크로가 여러 형식을 허용하는 경우에만 작동하지만 두 경우 모두에서 작동 을 사용한다는 점은 주목할 가치가 있습니다. 결과적으로 일부 사람들 progn은 항상 작동하기 때문에 항상 항상을 사용하는 것을 선호합니다 .


15
매크로와는 전혀 관련이 없습니다. 일부 함수와 매크로에는 소위 "암시 적 progn"이라는 의미가 있습니다. 즉, 여러 개의 성별을 별도의 인수로 받아들이고 순서대로 평가합니다. 다른 사람들은 여러 sexps를 순서대로 평가할 수있는 단일 인수 만 기대하거나 허용하지 않습니다. 그게 전부입니다 progn: 그것은 평가 될 때 progn순차적으로 sexp 인수를 평가하는 단일 sexp를 제공 할 수 있습니다 . (if true (progn a b c))와 비교하십시오 (when true a b c). 두 경우 모두 a, b그리고 c순서대로 평가됩니다.
Drew


4
유스 케이스의 99 %가 매크로 등에 사용된다는 것에 동의하지 않습니다. 모든 함수 나 매크로progn 에는 마지막으로 결과를 반환하기 전에 부작용에 대해 평가 된 여러 개의 sexps가 포함 된 sexp를 전달할 수 있습니다 . 매크로와는 전혀 관련이 없습니다. "예를 들어"매크로가 좋습니다. progn매크로에 존재하고 99 %가 매크로에 사용된다는 인상을주는 것은 잘못된 것입니다. progn일련 의 평가를 하나의 sexp 로 삽질하는 것에 관한 것이며 (주어진 예상 된 주장에 맞도록) 부작용 에 관한 입니다.
Drew

5
1. 매크로가 Lisp에 추가되기 훨씬 전인 1962 년 Lisp 1.5 ( 프로그램 기능 참조) progn에 도입되었습니다 . 목적은 부작용에 대한 식을 순차적으로 평가하는 것입니다. 2. Emacs 자체 가 Elisp 프로그래머에게 어떻게 소개 되는지 살펴 보십시오 . 간단한 사용 사례 는 코드를 참조하십시오 . prognprognzap-to-char
Drew

2
우리는 동의하지 않을 수 있습니다. 내 요점은 매크로와progn아무런 관련없다는 것입니다. 그 목적은 물론 " 여러 양식을 단일 양식으로 전달하는 것 "(귀하의 단어)-함수 또는 매크로 또는 특수 양식이든 " 순서대로 BODY 양식을 평가하고 마지막 양식의 값을 반환 "하는 것입니다 (doc 문자열 ). 이제는 언제나처럼 (“이날”, 참으로!). 순서화 된 평가는 부작용에 대해서만 중요합니다. 주어진 유스 케이스 (매크로 또는 아님)는 평가 순서를 신경 쓰거나 신경 쓰지 않을 수 있지만 관련이 없습니다. 그리고 이맥스 리스프 (Emacs Lisp)는 이런면에서 예외가 아닙니다.
Drew

10

progn 의 가장 중요한 이유 는 progn 문서 의 첫 번째 줄에 설명되어 있습니다 (강조 추가).

progn은 각 인수를 순서대로 평가 한 다음 마지막 인수 의 값을 리턴 하는 특수 양식입니다 .

추가:

progn이 없으면 시퀀스가 보장되지 않습니다. 특히 후속 표현식이 이전 표현식의 부작용 또는 리턴 값에 종속되는 경우입니다. progn은 실행 순서를 텍스트 순서와 동일하게 적용합니다. 실행을 구문 분석과 혼동하지 않도록 도와줍니다. 이 동작은 lisp 제어 구조와 함수형 프로그래밍의 기본으로 돌아갑니다. 다음은 lisp 참조 매뉴얼 에서 발췌 한 내용입니다 (강조 추가) .

기본 제공 제어 구조는 하위 양식이 반드시 순차적으로 평가되거나 평가되지 않아도되므로 특수 양식 입니다.

progn은 성능을 향상 시킵 니까 ?

파싱 ​​성능. 실행 성능. 기껏해야 성능은 같지만 마술처럼 성능을 향상 시키지는 않습니다.

프론 은 언제 사용 됩니까?

... 대부분의 경우 unwind-protect 내부 및 또는 , 또는 if 의 그 다음 부분에 있습니다.


왜 그렇게 중요한지 잘 모르겠습니다. 이맥스는 항상 순차적으로 평가합니다.
lunaryorn

2
@lunaryorn은 업데이트 된 답변을 참조하십시오.
Emacs User

편집 내용을 이해하는지 잘 모르겠습니다. 당연히 평가 순서 (예 :)가 다른 특수한 형태가 if있지만 일반 평가 순서 (예 : 최상위 형태, 기능 본문 등)는 텍스트입니다. 물론 어느 정도는 암시 적이 progn지만 일반적으로 progn 자신의 코드에서 사용 하는 것은 아닙니다 .
lunaryorn

나는 (elisp) Sequencing당신이 연결 하는 Elisp 수동 노드 가 모든 것을 말한다고 생각합니다.
바질

10

progn가족과 비교하는 것이 무엇인지 이해하는 더 좋은 방법 은 다음 prog1과 같습니다 prog2. n하거나 1또는 2이름의 일부는 결과에 관심이 목록에서 문을 의미합니다. 즉, progn반면에 포함 된 마지막 문장의 결과를 반환합니다 prog1첫 번째, 및 유사를 반환합니다 prog2.

오늘날이 기능은 프로그램이 마지막 명령문에서 리턴 될 것으로 기대하거나 리턴 할 항목을 명시 적으로 지시하는 것을 배우기 때문에 약간 어색해 보입니다. 따라서 prog1prog2매우 거의 사용되지 않습니다. 그러나 그것에 대해 생각하면 의미가 있으며 여기에 방법이 있습니다.

다른 프로그래밍 언어는 다른 전략을 사용하여 의미를 설명합니다. 리스프 패밀리는 과거의 의미론과 밀접하게 연결되어있었습니다. 자세히 설명하지 않으면 서 이런 종류의 의미론은 우리가 "표현"이 아닌 "표명"으로 알면서 특히 어려움을 겪습니다. 코드의 의미는 일반적으로 함수 조합 측면에서 생각되는 반면, 함수로 설명 할 수없는 "문장"은 (어떤 것으로 평가되지 않기 때문에) 다루기가 어렵습니다. 그러나 Lisp는 부작용을 허용하기 때문에 프로그래머는 때때로 표현식을 따르는 표현식에 영향을주지 않는 방식으로 값을 사용하지 않고 표현식을 사용하려고합니다. 그리고 이것은 progX가족이 들어오는 곳 입니다.

에서 C와 같은 언어로이 기능은 때때로로 알려져 시퀀스 포인트 (즉, ;,예를 들어). C progn와 같은 언어와 마찬가지로 Lisp와 같은 언어에 필수적 ;입니다. 쉽게 대체 할 수없는 언어의 기본 기능입니다. 그러나 C 스타일 언어와 달리 Lisp는 하위 수준의 구문을 완전히 숨겨서 구문 추상화를 작성하는 경향이 있습니다. 그리고 이것은 아마도 당신이 progn모든 것을 자주 사용 하지 않는 이유 일지 모르지만, 더 높은 수준의 언어 추상화 (매크로)를 구축 할 때 중요한 빌딩 블록 중 하나입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.