문제

한 후 그것을 통해 주요 부품의 입문 Lisp,나도 여전히 이해할 수 없었다 어떤 특별한 통신수 (quote) (또는 해당 ')함수는,아직 이것은 모든 패키지 코드가 나는 볼 수 있습니다.

그것은 무엇입니까?

도움이 되었습니까?

해결책

짧은 대답기본 평가 규칙을 우회하고 수행하십시오 ~ 아니다 표현식 (Symbol 또는 S-Exp)을 평가하여 유형대로 정확히 함수로 전달하십시오.

긴 답변 : 기본 평가 규칙

규칙적으로 (나중에 오게 될 것) 기능이 호출되면, 전달 된 모든 인수가 평가됩니다. 이것은 당신이 이것을 쓸 수 있음을 의미합니다.

(* (+ a 2)
   3)

차례로 평가합니다 (+ a 2), 평가함으로써 a 그리고 2. 기호의 값 a 현재 변수 바인딩 세트에서 찾은 다음 교체되었습니다. 말하다 a 현재 값 3에 묶여 있습니다.

(let ((a 3))
  (* (+ a 2)
     3))

우리는 얻을 것입니다 (+ 3 2), +는 3과 2 수율로 호출됩니다. 우리의 원래 양식은 이제 (* 5 3) 15를 산출합니다.

설명 quote 이미!

괜찮은. 위에서 볼 수 있듯이 함수에 대한 모든 인수가 평가되므로 전달하려면 상징 a 그리고 그 가치가 아니라 당신은 그것을 평가하고 싶지 않습니다. LISP 기호는 값으로 두 배가 될 수 있으며 다른 언어로 된 다른 언어에서 해시 테이블의 키와 같은 문자열을 사용했을 수있는 마커.

이것은 어디에 있습니다 quote Python 애플리케이션에서 자원 할당을 플로팅하고 싶지만 LISP에서 플롯을 작성하고 싶다고 가정 해보십시오. 파이썬 앱이 다음과 같은 일을하도록하십시오.

print("'(")
while allocating:
    if random.random() > 0.5:
        print(f"(allocate {random.randint(0, 20)})")
    else:
        print(f"(free {random.randint(0, 20)})")
    ...
print(")")

이렇게 보이는 출력을 제공합니다 (약간 예쁜) :

'((allocate 3)
  (allocate 7)
  (free 14)
  (allocate 19)
  ...)

내가 말한 것을 기억하십시오 quote ( "진드기") 기본 규칙이 적용되지 않습니까? 좋은. 그렇지 않으면 일어날 일은 그 가치입니다 allocate 그리고 free 찾아보고 우리는 그것을 원하지 않습니다. 우리의 LISP에서 우리는 다음을 원합니다.

(dolist (entry allocation-log)
  (case (first entry)
    (allocate (plot-allocation (second entry)))
    (free (plot-free (second entry)))))

위에 주어진 데이터의 경우 다음과 같은 일련의 기능 호출이 이루어 졌을 것입니다.

(plot-allocation 3)
(plot-allocation 7)
(plot-free 14)
(plot-allocation 19)

그러나 list?

글쎄, 때때로 당신 하다 주장을 평가하고 싶습니다. 숫자와 문자열을 조작하고 결과적인 것들의 목록을 반환하는 멋진 기능이 있다고 가정 해 봅시다. 허위로 시작합시다 :

(defun mess-with (number string)
  '(value-of-number (1+ number) something-with-string (length string)))

Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER (1+ NUMBER) SOMETHING-WITH-STRING (LENGTH STRING))

여기요! 그것은 우리가 원했던 것이 아닙니다. 우리는 원합니다 선택적으로 일부 인수를 평가하고 다른 주장을 상징으로 남겨 두십시오. #2를 시도하십시오!

(defun mess-with (number string)
  (list 'value-of-number (1+ number) 'something-with-string (length string)))

Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER 21 SOMETHING-WITH-STRING 3)

뿐만 아니라 quote, 하지만 backquote

훨씬 낫다! 불길하게,이 패턴은 (주로) 매크로에서 매우 일반적이므로 그 일을하는 데 특별한 구문이 있습니다. 백 크기 :

(defun mess-with (number string)
  `(value-of-number ,(1+ number) something-with-string ,(length string)))

사용하는 것과 같습니다 quote, 그러나 쉼표로 접두사를 통해 일부 인수를 명시 적으로 평가할 수있는 옵션이 있습니다. 결과는 사용과 동일합니다 list, 그러나 매크로에서 코드를 생성하는 경우 종종 반환 된 코드의 작은 부분 만 평가하려고하므로 백 크기가 더 적합합니다. 짧은 목록의 경우 list 더 읽기 쉬울 수 있습니다.

이봐, 당신은 잊었습니다 quote!

그렇다면 이것이 우리를 어디에 남겨 두나요? 아 맞아요 quote 실제로? 그것은 단순히 논쟁을 반환하지 않았다! 정기적 인 기능에 대해 처음에 말한 것을 기억하십니까? 일부 연산자/기능이 필요하다는 것이 밝혀졌습니다 ~ 아니다 그들의 주장을 평가하십시오. 예를 들어 - 다른 지점이 가져 가지 않으면 평가되는 것을 원하지 않을 것입니다. 소위 특수 운영자, 매크로와 함께, 그렇게 일하십시오. 특수 운영자는 또한 언어의 "공리"(최소한의 규칙 세트)입니다. 여기에는 LISP의 나머지 부분을 서로 다른 방식으로 결합하여 구현할 수 있습니다.

돌아가다 quote, 그렇지만:

Lisp> (quote spiffy-symbol)
SPIFFY-SYMBOL

Lisp> 'spiffy-symbol ; ' is just a shorthand ("reader macro"), as shown above
SPIFFY-SYMBOL

(스틸 뱅크 공통 LISP에서)와 비교합니다.

Lisp> spiffy-symbol
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD "initial thread" RUNNING   {A69F6A9}>:
  The variable SPIFFY-SYMBOL is unbound.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-INT:SIMPLE-EVAL-IN-LEXENV SPIFFY-SYMBOL #<NULL-LEXENV>)
0] 

없기 때문에 spiffy-symbol 현재 범위에서!

합산

quote, backquote (쉼표 포함) 및 list 목록을 작성하는 데 사용하는 일부 도구, 값 목록 일뿐 만 아니라 보았 듯이 경량으로 사용할 수 있습니다 ( struct) 데이터 구조!

더 배우고 싶다면 Peter Seibel의 책을 추천합니다. 실용적인 공통 LISP LISP 학습에 대한 실질적인 접근 방식은 이미 프로그래밍 중이라면. 결국 LISP 여행에서 패키지도 사용하기 시작합니다. Ron Garret 's 일반적인 LISP 패키지에 대한 바보 가이드 그것들에 대한 좋은 설명을 줄 것입니다.

행복한 해킹!

다른 팁

"나를 평가하지 마십시오"라고 말합니다. 예를 들어, 코드가 아닌 데이터로 목록을 사용하려면 그 앞에 견적을 넣습니다. 예를 들어,

(print '(+ 3 4)) "(+ 3 4)"인쇄(print (+ 3 4)) 인쇄 "7"

다른 사람들은 이 질문에 답을 훌륭하게,부다페스트 Benkard 제공한 경고입니다.

를 사용하지 않는 견적을 만드는 목록은 당신이 나중에 수정할 수 있습니다.스펙을 허용하면 컴파일러 치료를 인용해 목록으로 상수입니다.종종 컴파일러 최적화를 상수로 만들기에 대한 단일 값을 메모리에서 다음을 참조하는 단일 값이 모든 위치에서 지속적인 나타납니다.다시 말해서,그것을 취급할 수 있는 일정한 다음과 같는 익명으로 글로벌 변수입니다.

이 발생할 수 있습니다 분명 문제입니다.를 수정하는 경우에 일정한,그것은 매우 잘 수정을 다른 용도의 동일한 상수로서 완전하게 관련이 없는 코드입니다.예를 들어,당신은 비교할 수 있습 몇 가지 변수'(1 1)어떤 기능,그리고 완전히 다른 기능,목록을 시작으로'(1 는 1)그리고 더 많은 물건을 추가합니다.에 따라 실행하는 이러한 기능을 찾을 수 있습니다 첫 번째 함수와 일치하지 않는 것이 제대로 있기 때문에,더 이상 그것이 지금 비교하려는 변수'(1 1 2 3 5 8 13), 는 두 번째 함수를 반환합니다.이러한 두 가지 기능을 완전하게 관련이지만,그들에 대한 효력이 있기 때문에 서로의 사용의 상수.심지어 나쁜 영향을 미쳤처럼 일어날 수있는 완벽하게 정상적인 목록을 반복 갑자기 무한한 보안 시스템을 제공합니다.

사용 견적이 필요할 때 일정한 목록 등에 대한 비교입니다.사용하면 목록은 당신이 될 수정 결과입니다.

이 질문에 대한 한 가지 대답에 따르면 인용문은 "목록 데이터 구조를 만듭니다"라고 말합니다. 이것은 옳지 않습니다. 인용문은 이것보다 더 근본적입니다. 실제로 인용문은 사소한 운영자입니다. 그 목적은 예방하다 전혀 일어나지 않는 모든 것. 특히, 그것은 아무것도 만들지 않습니다.

(인용 X)는 기본적으로“아무것도하지 말고 X를 줘”입니다. x는 (QUOTE (ABC)) 또는 (QUOTE FOO)와 같이 목록이 될 필요가 없습니다. 그것은 어떤 대상이든 될 수 있습니다. 실제로, (목록 'QUOTED-OBJECT)에 의해 생성 된 목록을 평가 한 결과는 항상 객체가 무엇이든간에 항상 반환됩니다.

이제 (QUOT (ABC))가 요소가 A, B, C 인 목록을 만든 것처럼 보이는 이유는 그러한 목록이 실제로 반환되는 것입니다. 그러나 견적 양식이 평가 될 때, 목록은 일반적으로 코드를 실행하기 전에 로더 또는 리더에 의해 생성 된 (인용 형식의 구성 요소로서) 이미 존재했습니다.

초보자를 상당히 자주 여행하는 경향이있는 한 가지 의미는 견적 양식으로 반환 된 목록을 수정하는 것이 매우 현명하지 않다는 것입니다. 견적으로 반환 된 데이터는 모든 의도와 목적으로 암호 따라서 실행되므로 읽기 전용으로 취급되어야합니다!

견적은 양식의 실행 또는 평가를 방지하여 대신 데이터로 전환합니다. 일반적으로 데이터를 평가하여 데이터를 실행할 수 있습니다.

인용문은 목록 데이터 구조를 만듭니다. 예를 들어 다음은 다음과 같습니다.

(quote a)
'a

목록 (또는 나무)을 만드는 데 사용될 수도 있습니다.

(quote (1 2 3))
'(1 2 3)

당신은 아마도 LISP에서 입문서를 얻는 것이 가장 좋습니다. 실용적인 공통 LISP (온라인을 읽을 수 있습니다).

논쟁의 가치를 전달하는 대신 논쟁 자체를 통과하려면 인용문을 사용합니다. C 프로그래밍 언어로 사용할 수없는 목록, 쌍 및 원자를 사용하는 동안 통과하는 절차와 관련이 있습니다 (대부분의 사람들은 C 프로그래밍을 사용하여 프로그래밍을 시작하므로 혼란스러워) LISP의 방언 인 체계 프로그래밍 언어의 코드입니다. 이 코드를 이해할 수 있다고 생각합니다.

(define atom?              ; defining a procedure atom?
  (lambda (x)              ; which as one argument x
(and (not (null? x)) (not(pair? x) )))) ; checks if the argument is atom or not
(atom? '(a b c)) ; since it is a list it is false #f

마지막 줄 (Atom? 'ABC)은 ABC가 원자인지 아닌지 확인하는 절차로 ABC를 전달하지만 (Atom? ABC) ABC의 값을 확인하고 값을 전달합니다. 그것. 우리는 그것에 어떤 가치도 제공하지 않았습니다

에 Emacs Lisp:

무엇을 인용될 수 있습니다?

목록과 기호입니다.

을 인용하수를 평가하수 자체:'5 와 동일 5.

무슨 일이 발생할 때 당신을 인용을 나열?

예를 들어:

'(one two)

(list 'one 'two) 는 평가

(list (intern "one") (intern ("two"))).

(intern "one") 성 상징이라는"하나"그리고 상점에서"중심"해시지도는,그래서 당신은 언제든지 말 'one 다음의 상징이라는 이름 "one" 것에는 중부시 지도입니다.

하지만 무엇입니다.

예를 들어,OO-언어(Java/자바스크립트/Python)기호로 나타낼 수 있습으로젝트 name 필드 기호의 이름처럼 "one" 위고는 데이터 및/또는 코드로 연결 될 수 있습으로 그것이 이 개체입니다.

그래서 기호에서는 파이썬 구현 될 수있다:

class Symbol:
   def __init__(self,name,code,value):
       self.name=name
       self.code=code
       self.value=value

에 Emacs Lisp 예를 들어 상징이 있을 수 있는 1)그와 관련된 데이터과(동시에 동일한 기호)2)코드 관련 컨텍스트에 따라,데이터 또는 이 코드가 호출됩니다.

예를 들어,Elisp:

(progn
  (fset 'add '+ )
  (set 'add 2)
  (add add add)
)

4.

(add add add) 다음으로 계산됩니다.

(add add add)
(+ add add)
(+ 2 add)
(+ 2 2)
4

그래서 예를 들어,사용 Symbol 클래스 정의에서는 파이썬 위 이 add ELisp-기호로 작성할 수 있습니에서는 파이썬 Symbol("add",(lambda x,y: x+y),2).

많은 감사한 사람들에 IRC#이맥스를 설명하기 위한 기호 및 시세요.

인용문은 인수의 내부 표현을 반환합니다. 어떤 인용문에 대한 너무 많은 설명을 통해 쟁기를 한 후 그렇지 않습니다 그렇습니다. 그때는 조명 갈매가 계속되었습니다. 내가 인용했을 때 REPL이 기능 이름을 상류로 변환하지 않았다면, 나에게 시작되지 않았을 수도 있습니다.

그래서. 일반 LISP 기능은 인수를 내부 표현으로 변환하고 인수를 평가하며 기능을 적용합니다. 인용문은 주장을 내부 표현으로 전환하고 그 주장을 반환합니다. 기술적으로 인용문이 "평가하지 마십시오"라고 말하는 것은 옳습니다. 그러나 그것이 무엇을했는지 이해하려고 할 때 그것이하지 않는 일을 말해주었습니다. 내 토스터는 LISP 기능도 평가하지 않습니다. 그러나 그것은 당신이 토스터가하는 일을 설명하는 방법이 아닙니다.

anoter 짧은 답변 :

quote 그것을 평가하지 않고 의미합니다 역 관리 인용문이지만 떠나십시오 뒷문.

좋은 추천 :

EMACS LISP 참조 매뉴얼은 매우 명확하게 만듭니다

9.3 인용

특별 양식 견적은 평가하지 않고 서면으로 단일 인수를 반환합니다. 이것은 프로그램에 자체 평가하는 객체가 아닌 상수 기호와 목록을 포함시키는 방법을 제공합니다. (숫자, 문자열 및 벡터와 같은 자기 평가 대상을 인용 할 필요는 없습니다.)

특별 양식 : 인용 대상

This special form returns object, without evaluating it. 

인용문은 프로그램에서 자주 사용되므로 LISP는 편리한 읽기 구문을 제공합니다. Apostrophe 캐릭터 ( '' ') 뒤에 LISP 객체 (읽기 구문)가 첫 번째 요소가 인용되고 두 번째 요소가 객체 인 목록으로 확장됩니다. 따라서 읽기 구문 'X는 (QUOTE X)에 대한 약어입니다.

다음은 인용문을 사용하는 표현의 몇 가지 예입니다.

(quote (+ 1 2))
     ⇒ (+ 1 2)

(quote foo)
     ⇒ foo

'foo
     ⇒ foo

''foo
     ⇒ (quote foo)

'(quote foo)
     ⇒ (quote foo)

9.4 역 관리

Backquote Construct는 목록을 인용 할 수 있지만 해당 목록의 요소를 선택적으로 평가할 수 있습니다. 가장 간단한 경우, 특별한 양식 인용문과 동일합니다 (이전 섹션에서 설명; 인용 참조). 예를 들어,이 두 형태는 동일한 결과를 산출합니다.

`(a list of (+ 2 3) elements)
     ⇒ (a list of (+ 2 3) elements)

'(a list of (+ 2 3) elements)
     ⇒ (a list of (+ 2 3) elements)

스페셜 마커 ','역용자 인수 내부는 일정하지 않은 값을 나타냅니다. EMACS LISP 평가자는 ','의 주장을 평가하고 값을 목록 구조에 넣습니다.

`(a list of ,(+ 2 3) elements)
     ⇒ (a list of 5 elements)

',', '대체는 목록 구조의 더 깊은 수준에서 허용됩니다. 예를 들어:

`(1 2 (3 ,(+ 4 5)))
     ⇒ (1 2 (3 9))

특수 마커 '@'를 사용하여 평가 된 값을 결과 목록에 스플라이킹 할 수도 있습니다. 스 플린트 목록의 요소는 결과 목록의 다른 요소와 동일한 수준의 요소가됩니다. '' '를 사용하지 않는 동등한 코드는 종종 읽을 수 없습니다. 여기 몇 가지 예가 있어요.

(setq some-list '(2 3))
     ⇒ (2 3)

(cons 1 (append some-list '(4) some-list))
     ⇒ (1 2 3 4 2 3)

`(1 ,@some-list 4 ,@some-list)
     ⇒ (1 2 3 4 2 3)
Code is data and data is code.  There is no clear distinction between them.

이것은 LISP 프로그래머가 알고있는 고전적인 진술입니다.

코드를 인용하면 해당 코드는 데이터입니다.

1 ]=> '(+ 2 3 4)
;Value: (+ 2 3 4)

1 ]=> (+ 2 3 4)
;Value: 9

코드를 인용하면 결과는 해당 코드를 나타내는 데이터입니다. 따라서 프로그램을 나타내는 데이터로 작업하려면 해당 프로그램을 인용합니다. 이것은 목록뿐만 아니라 원자 표현에도 유효합니다.

1 ]=> 'code
;Value: code

1 ]=> '10
;Value: 10

1 ]=> '"ok"
;Value: "ok"

1 ]=> code
;Unbound variable: code

LISP에 포함 된 프로그래밍 언어를 만들고 싶다고 가정합니다. '(+ 2 3)) 그리고 그것은 프로그램에 의미 적 해석을 제공함으로써 당신이 만든 언어로 코드로 해석됩니다. 이 경우 데이터를 유지하려면 견적을 사용해야합니다. 그렇지 않으면 외부 언어로 평가됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top