변수 이름 앞에 작은 따옴표를 사용해야 할 시점과 시점을 아는 방법은 무엇입니까?


31

나는 아래를 가지고있다 :

(setq some-variable "less")

왜 작은 따옴표를 사용해야 boundp하지만 혼동하지 않는지 혼란 스럽 습니다 bound-and-true-p.

예 1 :

(when (boundp 'some-variable) 
   (message "some-variable is %s" some-variable))

결과:

"일부 변수가 적습니다"

실시 예 2a :

(when (bound-and-true-p some-variable) ;; Note that using single-quote causes error
   (message "some-variable is %s" some-variable))

결과:

"일부 변수가 적습니다"

예 2b :

(when (bound-and-true-p 'some-variable) ;; Note that using single-quote causes error
   (message "some-variable is %s" some-variable))

결과:

및 : 잘못된 유형 인수 : symbolp, (일부 변수 인용)


5
그것은 언급 할만큼 가치의 setq의미 set quoted, 원래로 확장하는 매크로이었다 (set 'some-variable "less"). 일반적으로 Elisp는 인용 된 인수와 인용되지 않은 인수에 대해 일관되게 일치하지 않지만 값 대신 변수와 상호 작용 해야하는 함수 (매크로가 아닌)는 인용 된 인수를 취합니다 ( setq주요 예외).
shosti

2
FWIW bound-and-true-p는 바보 같은 매크로입니다. 또는 오히려 그 이름은 바보입니다. 원할 때 99.99 %의 시간 (and (boundp 'FOO) FOO)의 값FOO사용합니다 . 당신은 진실의 가치를 얻기 위해 그것을하지 않습니다. (1) 매크로가 필요하지 않습니다. 대체하는 코드는 사소하고 작습니다. (2) 이름이 잘못되었습니다-변수 값이 아닌지 테스트하는 것이 아니라 변수 값에 관한 것입니다 nil.
Drew

답변:


24

짧은 답변

변수 자체를 사용하려는 경우을 사용하십시오 'some-variable. 변수에 저장된 값을 사용하려는 경우을 사용하십시오 some-variable.

  • boundp은 symbol을 사용하므로 함수를 포함하여 바인딩 할 수있는 모든 것을 볼 수 있습니다. 값이 아닌 일치하는 기호가 있는지 여부 만 걱정합니다.
  • bound-and-truep는 var를 사용하고 값을 반환합니다. 이 경우 기호 값을 함수에 제공해야합니다. var가 바인딩 된 심볼이 없거나 값이 nil이면 nil을 반환합니다.

설명

매뉴얼 정의에 대해서는 매뉴얼을 참조하십시오 .

'그리고 (quote ...)둘 다 이맥스 혀짤배기에서 동일한 목적을 수행합니다.

이것의 목적은 평가되지 않은 양식을 평가하기보다는 주변 환경으로 전달하는 것입니다.

귀하의 예에서 우리가 다음을 더 높게 가정했다고 가정하십시오.

(setq some-variable "less") ;; Rather than just 't for clarity

그런 다음 평가는 다음과 같습니다.

(when (boundp 'some-variable) 
   (message "some-variable is %s" some-variable))
;; ==> (boundp 'some-variable) ; 't
;; ==> some-variable is "less"

인용이없는 반면 :

(when (boundp some-variable) ;; Note that using single-quote causes error
   (message "some-variable is %s" some-variable))
;; ==> (boundp "less") ; "less" is not a variable. -> Error

Lisp는 실제 변수 (또는 목록 또는 함수 이름)가 전달되도록 평가할 수없는 양식을 인용하여 양식에 도달하면 양식을 평가합니다.


감사! 귀하의 답변으로 두 가지 소스로 뛰어 들어 해결책을 찾도록 도와주었습니다. 또한 명확한 예를 들어 질문을 업데이트했습니다.
Kaushal Modi

6
나는 이것이 op에 도움이 된 것을 기쁘게 생각하지만 실제로 같은 질문을하는 다른 사람들에게 유용한 방법으로 질문에 대답하지는 않습니다. 기호를 인용해야하거나 그렇지 않은 경우에만 설명합니다. 당신은 그것이 사실이 아닌 이유를 설명하지 않으며 bound-and-truep질문은 사용 할 때 인용해야 boundp하지만 사용 할 때 인용 해야하는 이유는 아닙니다 bound-and-truep.
tarsius

@tarsius 사실의 차이 등 boundp기호 (평가되지 않은)을 필요로하고 bound-and-truep(초기에 응답 한 후 편집) 총알 점에서 변수의 값을 필요로
조나단 거머리-Pepin에를

나는 doc-string이 그렇게 말하는 것을 언급하는 대신 왜 그것이 그렇게되는지 언급하는 것이 필수적이라고 생각합니다 (매크로는 평가하지 않기로 결정할 수도 있습니다). 나는 이것이 매우 좋은 질문이라고 생각하며 boundp와 bound-and-true-p는 단지 예일뿐입니다. 문제는 실제로 평가 규칙에 대해 배우려는 욕구입니다.
tarsius

@tarsius이 답변에서 설명하는 평가 규칙이 아닙니까? 적어도 인용 만 포함하는 기본적인 것들은 ... 당신의 대답은 확실히 더 완벽하지만, 주제를 훨씬 넘어서는 것입니까?
T. Verron

16

기능하지 않은 위치에있는 기호는 변수의 이름으로 취급됩니다. 이어 (function variable) function(개구 괄호 후) 함수 위치에 존재하고 variable아니다. 명시 적으로 인용 된 변수가 해당 값으로 대체되지 않는 한.

작성한다면 (boundp my-variable)"변수로 my-variable바인드 된 변수의 값에 저장된 기호"를 의미하고 "변수로 바인드 된 기호가 아닙니다"를 의미합니다 my-variable.

그렇다면 왜 bound-and-truep다르게 행동합니까?

이것은 매크로이며 일반적인 (함수) 평가 규칙은 여기에 적용되지 않으며 매크로는 인수의 평가 여부와시기를 자유롭게 결정할 수 있습니다. 실제로 매크로가하는 일은 어떻게 든 인수를 변환하고 결과를 목록으로 반환 한 다음 평가됩니다. 변환 및 최종 평가는 매크로 확장 시간과 평가 시간이라고하는 다른 시간에 발생합니다.

정의는 bound-and-true-p다음과 같습니다.

(defmacro bound-and-true-p (var)
  "Return the value of symbol VAR if it is bound, else nil."
  `(and (boundp (quote ,var)) ,var))

이것은 lisp 매크로와 다른 리더 매크로를 사용합니다 (아래에서 더 자세히 설명). 이것을 복잡하게하지 않기 위해 독자 매크로를 사용하지 마십시오.

(defmacro bound-and-true-p (var)
  "Return the value of symbol VAR if it is bound, else nil."
  (list 'and (list 'boundp (list 'quote var)) var))

당신이 쓰는 경우

(bound-and-true-p my-variable)

처음으로 "번역"됩니다

(and (boundp 'my-variable) my-variable)

그리고 그렇지 않은 nil경우 또는 그렇지 my-variable않은 경우 (물론) boundp값을 반환하여 평가 됩니다 .my-variablenil


확장이 아닌 것을 알았을 것입니다

(and (boundp (quote my-variable)) my-variable)

우리가 예상했던대로. quote매크로 나 함수가 아닌 특수한 형식입니다. 매크로와 마찬가지로 특수 형식은 인수로 무엇이든 할 수 있습니다. 이 특별한 특수 형식은 단순히 기호의 변수 값 대신 인수, 여기서 기호를 반환합니다. 이것이 실제로이 특별한 형태의 유일한 목적입니다 : 평가 방지! 매크로는 스스로 그렇게 할 수 없으므로 그렇게해야합니다 quote.

무슨 일이야 '? 그것은 인 리더 매크로 위에서 언급 같은 아니다 LISP 매크로 . 매크로는 코드 / 데이터를 변환하는 데 사용되는 반면, 텍스트를 코드 / 데이터로 변환하기 위해 텍스트를 읽을 때 이전에 리더 매크로가 사용됩니다.

'something

짧은 형식입니다

(quote something)

`bound-and-true-p또한 실제 정의에 사용되는 것은 리더 매크로입니다. 같이이 기호를 인용하는 경우 `symbol는 동일합니다 'symbol,하지만 같이 목록을 인용하는 데 사용되는 경우 `(foo bar ,baz)가로 시작되는 형태로 다르게 작동 ,평가된다.

`(constant ,variable)

에 해당

(list (quote constant) variable))

인용되지 않은 기호가 때때로 평가되고 (값으로 대체 됨) 때로는 그렇지 않은 이유에 대한 질문에 답해야합니다. 매크로는 quote심볼 평가를 막기 위해 사용할 수 있습니다 .

그러나 왜 bound-and-true-p매크로 boundp가 아닌가? 런타임까지 알려지지 않은 임의의 심볼이 심볼로 묶여 있는지 확인할 수 있어야합니다. boundp인수가 자동으로 인용 되면 불가능합니다 .

bound-and-true-p알려진 변수가 정의되어 있는지 확인하고 해당 변수를 사용하는 경우 해당 값을 사용합니다. 라이브러리가 다음과 같이 타사 라이브러리에 대한 선택적 종속성 이있는 경우 유용합니다 .

(defun foo-get-value ()
  (or (bound-and-true-p bar-value)
      ;; we have to calculate the value ourselves
      (our own inefficient or otherwise undesirable variant)))

bound-and-true-p함수로 정의 할 수 있고 인수를 인용해야하지만 매크로에 대해 관심있는 변수를 미리 알고있는 경우를 위해을 입력하지 않아도됩니다 '.


놀랍게도 잘 대답했습니다.
Charles Ritchie

2

소스 코드에서 boundp:

DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0,
      doc: /* Return t if SYMBOL's value is not void.
Note that if `lexical-binding' is in effect, this refers to the
global value outside of any lexical scope.  */)

boundpsymbol입력으로 기대합니다 . 'some-variable변수에 대한 기호 some-variable입니다.

소스 코드에서 bound-and-true-p:

(defmacro bound-and-true-p (var)
  "Return the value of symbol VAR if it is bound, else nil."
  `(and (boundp (quote ,var)) ,var))

bound-and-true-pvariable입력으로 기대합니다 .

bound-and-true-p매크로 내부에서을 수행하여 기호를 가져옵니다 (quote ,var). 따라서 입력이 some-variable이면 (quote ,var)결과가됩니다 'some-variable.

그러나 입력 'some-variablebound-and-true-p에 입력 하면 오류가 발생합니다. and: Wrong type argument: symbolp, (quote some-variable)매크로가 'some-variable입력에서 기호 ( )를 기대하지 않기 때문 입니다.


그냥 머리 위로. ''symbol 수행 메이크업 감각. 의미 (quote (quote symbol))합니다. 오류가 발생하는 이유는에 대한 올바른 인수가 아니기 때문 boundp입니다.
Malabarba

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