Lisp에서 '(또는 따옴표)를 언제 사용합니까?
Lisp 입문 책의 주요 부분을 살펴본 후에도 특수 연산자 (quote)
(또는 동등한 '
) 함수가 하는 일을 여전히 이해할 수 없었지만 이것은 내가 본 Lisp 코드 전체에 걸쳐 있습니다.
그것은 무엇을합니까?
단답형 기본 평가 규칙을 무시하고 표현식 (기호 또는 s-exp)을 평가 하지 않고 입력 한대로 정확히 함수에 전달합니다.
긴 답변 : 기본 평가 규칙
정규 (나중에 설명하겠습니다) 함수가 호출되면 전달 된 모든 인수가 평가됩니다. 이것은 다음과 같이 작성할 수 있음을 의미합니다.
(* (+ a 2)
3)
설정에 어떤 평가하여 (+ a 2)
평가하여, a
심볼의 값과 2 a
의 현재 변수 결합 세트에서 조회하고 대체된다. Say a
는 현재 값 3에 바인딩되어 있습니다.
(let ((a 3))
(* (+ a 2)
3))
우리는 (+ 3 2)
, +를 3과 2에서 호출하여 5를 산출합니다. 원래 형식은 이제 (* 5 3)
15를 산출합니다.
quote
이미 설명하십시오 !
좋구나. 위에서 볼 수 있듯이 함수에 대한 모든 인수가 평가되므로 값이 아닌 기호 를 전달 a
하려는 경우 평가하고 싶지 않습니다. Lisp 기호는 값으로 두 배가 될 수 있으며 다른 언어에서 해시 테이블에 대한 키와 같은 문자열을 사용한 마커도 사용할 수 있습니다.
이것이 quote
들어오는 곳 입니다. Python 응용 프로그램에서 리소스 할당을 플로팅하려는 대신 Lisp에서 플로팅을 수행한다고 가정 해 보겠습니다. Python 앱이 다음과 같은 작업을 수행하도록합니다.
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
실제로 무엇을 하는가? 단순히 평가되지 않은 인수를 반환합니다! 처음에 정규 함수에 대해 말한 것을 기억하십니까? 일부 연산자 / 함수 는 인수를 평가 하지 않아도됩니다 . IF와 같은-그렇지 않은 경우 else 분기가 평가되는 것을 원하지 않습니까? 소위 특수 연산자 는 매크로와 함께 작동합니다. 특수 연산자는 또한 언어의 "공리"(최소한의 규칙 집합)이며 다른 방식으로 결합하여 나머지 Lisp를 구현할 수 있습니다.
quote
하지만로 돌아 가기 :
Lisp> (quote spiffy-symbol)
SPIFFY-SYMBOL
Lisp> 'spiffy-symbol ; ' is just a shorthand ("reader macro"), as shown above
SPIFFY-SYMBOL
(Steel-Bank Common 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의 책 Practical Common Lisp 를 추천합니다. 결국 Lisp 여정에서 패키지도 사용하기 시작합니다. Ron Garret의 The Idiot 's Guide to Common Lisp Packages 는 이에 대한 좋은 설명을 제공합니다.
해피 해킹!
"나를 평가하지 마십시오"라고되어 있습니다. 예를 들어 목록을 코드가 아닌 데이터로 사용하려면 그 앞에 따옴표를 붙입니다. 예를 들면
(print '(+ 3 4))
"(+ 3 4)"를 (print (+ 3 4))
인쇄하고 "7"을 인쇄합니다.
다른 사람들이이 질문에 훌륭하게 대답했고 Matthias Benkard는 훌륭한 경고를 내놓았습니다.
나중에 수정할 목록을 만들 때 견적을 사용하지 마십시오. 사양을 통해 컴파일러는 인용 된 목록을 상수로 처리 할 수 있습니다. 종종 컴파일러는 메모리에 단일 값을 만든 다음 상수가 나타나는 모든 위치에서 해당 단일 값을 참조하여 상수를 최적화합니다. 즉, 상수를 익명의 전역 변수처럼 취급 할 수 있습니다.
This can cause obvious problems. If you modify a constant, it may very well modify other uses of the same constant in completely unrelated code. For example, you may compare some variable to '(1 1) in some function, and in a completely different function, start a list with '(1 1) and then add more stuff to it. Upon running these functions, you may find that the first function doesn't match things properly anymore, because it's now trying to compare the variable to '(1 1 2 3 5 8 13), which is what the second function returned. These two functions are completely unrelated, but they have an effect on each other because of the use of constants. Even crazier bad effects can happen, like a perfectly normal list iteration suddenly infinite looping.
Use quote when you need a constant list, such as for comparison. Use list when you will be modifying the result.
One answer to this question says that QUOTE “creates list data structures”. This isn't quite right. QUOTE is more fundamental than this. In fact, QUOTE is a trivial operator: Its purpose is to prevent anything from happening at all. In particular, it doesn't create anything.
What (QUOTE X) says is basically “don't do anything, just give me X.” X needn't be a list as in (QUOTE (A B C)) or a symbol as in (QUOTE FOO). It can be any object whatever. Indeed, the result of evaluating the list that is produced by (LIST 'QUOTE SOME-OBJECT) will always just return SOME-OBJECT, whatever it is.
Now, the reason that (QUOTE (A B C)) seems as if it created a list whose elements are A, B, and C is that such a list really is what it returns; but at the time the QUOTE form is evaluated, the list has generally already been in existence for a while (as a component of the QUOTE form!), created either by the loader or the reader prior to execution of the code.
One implication of this that tends to trip up newbies fairly often is that it's very unwise to modify a list returned by a QUOTE form. Data returned by QUOTE is, for all intents and purposes, to be considered as part of the code being executed and should therefore be treated as read-only!
The quote prevents execution or evaluation of a form, turning it instead into data. In general you can execute the data by then eval'ing it.
quote creates list data structures, for example, the following are equivalent:
(quote a)
'a
It can also be used to create lists (or trees):
(quote (1 2 3))
'(1 2 3)
You're probably best off getting an introductary book on lisp, such as Practical Common Lisp (which is available to read on-line).
When we want to pass an argument itself instead of passing the value of the argument then we use quote. It is mostly related to the procedure passing during using lists, pairs and atoms which are not available in C programming Language ( most people start programming using C programming, Hence we get confused) This is code in Scheme programming language which is a dialect of lisp and I guess you can understand this code.
(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
The last line (atom? 'abc) is passing abc as it is to the procedure to check if abc is an atom or not, but when you pass(atom? abc) then it checks for the value of abc and passses the value to it. Since, we haven't provided any value to it
In Emacs Lisp:
What can be quoted ?
Lists and symbols.
Quoting a number evaluates to the number itself: '5
is the same as 5
.
What happens when you quote lists ?
For example:
'(one two)
evaluates to
(list 'one 'two)
which evaluates to
(list (intern "one") (intern ("two")))
.
(intern "one")
creates a symbol named "one" and stores it in a "central" hash-map, so anytime you say 'one
then the symbol named "one"
will be looked up in that central hash-map.
But what is a symbol ?
For example, in OO-languages (Java/Javascript/Python) a symbol could be represented as an object that has a name
field, which is the symbol's name like "one"
above, and data and/or code can be associated with it this object.
So an symbol in Python could be implemented as:
class Symbol:
def __init__(self,name,code,value):
self.name=name
self.code=code
self.value=value
In Emacs Lisp for example a symbol can have 1) data associated with it AND (at the same time - for the same symbol) 2) code associated with it - depending on the context, either the data or the code gets called.
For example, in Elisp:
(progn
(fset 'add '+ )
(set 'add 2)
(add add add)
)
evaluates to 4
.
Because (add add add)
evaluates as:
(add add add)
(+ add add)
(+ 2 add)
(+ 2 2)
4
So, for example, using the Symbol
class we defined in Python above, this add
ELisp-Symbol could be written in Python as Symbol("add",(lambda x,y: x+y),2)
.
Many thanks for folks on IRC #emacs for explaining symbols and quotes to me.
Quote returns the internal representation of its arguments. After plowing through way too many explanations of what quote doesn't do, that's when the light-bulb went on. If the REPL didn't convert function names to UPPER-CASE when I quoted them, it might not have dawned on me.
So. Ordinary Lisp functions convert their arguments into an internal representation, evaluate the arguments, and apply the function. Quote converts its arguments to an internal representation, and just returns that. Technically it's correct to say that quote says, "don't evaluate", but when I was trying to understand what it did, telling me what it doesn't do was frustrating. My toaster doesn't evaluate Lisp functions either; but that's not how you explain what a toaster does.
Anoter short answer:
quote
means without evaluating it, and backquote is quote but leave back doors.
A good referrence:
Emacs Lisp Reference Manual make it very clear
9.3 Quoting
The special form quote returns its single argument, as written, without evaluating it. This provides a way to include constant symbols and lists, which are not self-evaluating objects, in a program. (It is not necessary to quote self-evaluating objects such as numbers, strings, and vectors.)
Special Form: quote object
This special form returns object, without evaluating it.
Because quote is used so often in programs, Lisp provides a convenient read syntax for it. An apostrophe character (‘'’) followed by a Lisp object (in read syntax) expands to a list whose first element is quote, and whose second element is the object. Thus, the read syntax 'x is an abbreviation for (quote x).
Here are some examples of expressions that use quote:
(quote (+ 1 2))
⇒ (+ 1 2)
(quote foo)
⇒ foo
'foo
⇒ foo
''foo
⇒ (quote foo)
'(quote foo)
⇒ (quote foo)
9.4 Backquote
Backquote constructs allow you to quote a list, but selectively evaluate elements of that list. In the simplest case, it is identical to the special form quote (described in the previous section; see Quoting). For example, these two forms yield identical results:
`(a list of (+ 2 3) elements)
⇒ (a list of (+ 2 3) elements)
'(a list of (+ 2 3) elements)
⇒ (a list of (+ 2 3) elements)
The special marker ‘,’ inside of the argument to backquote indicates a value that isn’t constant. The Emacs Lisp evaluator evaluates the argument of ‘,’, and puts the value in the list structure:
`(a list of ,(+ 2 3) elements)
⇒ (a list of 5 elements)
Substitution with ‘,’ is allowed at deeper levels of the list structure also. For example:
`(1 2 (3 ,(+ 4 5)))
⇒ (1 2 (3 9))
You can also splice an evaluated value into the resulting list, using the special marker ‘,@’. The elements of the spliced list become elements at the same level as the other elements of the resulting list. The equivalent code without using ‘`’ is often unreadable. Here are some examples:
(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.
This is a classical statement any lisp programmer knows.
When you quote a code, that code will be data.
1 ]=> '(+ 2 3 4)
;Value: (+ 2 3 4)
1 ]=> (+ 2 3 4)
;Value: 9
When you quote a code, the result will be data that represent that code. So, when you want to work with data that represents a program you quote that program. This is also valid for atomic expressions, not only for lists:
1 ]=> 'code
;Value: code
1 ]=> '10
;Value: 10
1 ]=> '"ok"
;Value: "ok"
1 ]=> code
;Unbound variable: code
Supposing you want to create a programming language embedded in lisp -- you will work with programs that are quoted in scheme (like '(+ 2 3)
) and that are interpreted as code in the language you create, by giving programs a semantic interpretation. In this case you need to use quote to keep the data, otherwise it will be evaluated in external language.
참고URL : https://stackoverflow.com/questions/134887/when-to-use-or-quote-in-lisp
'programing tip' 카테고리의 다른 글
DialogFragment를 올바르게 닫는 방법은 무엇입니까? (0) | 2020.08.11 |
---|---|
GoogleTest에서 특정 테스트 케이스를 실행하는 방법 (0) | 2020.08.11 |
풀하기 전에 로컬과 github의 차이점을 확인하는 방법 (0) | 2020.08.11 |
자바 스크립트 i ++ 대 ++ i (0) | 2020.08.11 |
PHP에서 추상 클래스는 무엇입니까? (0) | 2020.08.11 |