2009-12-05 5 views

답변

12

그들은 꽤 상호 교환 가능합니다. 대답은 function입니다.은 람다를 바이트로 컴파일 할 수 있습니다. 반면에 다른 두 바이트는 컴파일되지 않습니다 (그리고 동등합니다). 참고 : 이것은 실제로이 람다를 바이트로 컴파일한다는 것을 의미하지 않습니다.

어떻게 알 수 있습니까? 약간의 Emacs lisp 내성 검사는 몇 가지 단서를 제공합니다. 시작하려면 : C-H F 기능 RET은 :

기능은 'C 소스 코드'에 특별한 형태입니다.

(기능 ARG)

추천 '인용'이지만 함수이다 개체 바람직하다. 바이트의 컴파일에서 'function'은 인수를 컴파일합니다. 'quote' 할 수 없습니다.

좋아

, 그래서 (function (lambda ...))'(lambda ...)의 차이의 첫 번째는 안전하게 표현을 컴파일 할 수있는 바이트 컴파일러를 알려줍니다. 그들은 단지 숫자의 목록이 될 수도에 대한 '반면 에드 표현은 반드시 (컴파일되지 않을 수 있습니다

그냥 맨손으로 (lambda ...) 채널 F 람다 RET 쇼에 대해 어떻게

:.?

람다입니다 `subr.el '의 리스프 매크로.

(람다 인수 [참조 문 [인터랙티브] 본체)

복귀 람다 식. 양식 (lambda args docstring 대화 형 본문)은 자체 인용입니다. 람다 표현을 평가 한 결과는 표현 자체입니다. 람다 식은 다음 가 로서 심볼의 함수 값을 저장 즉 함수로 처리 될 수있다

따라서 (lambda ...)'(lambda ...)는 'funcall'또는 'mapcar 등등'등에 합격 동등한.

#'(lambda ...) 또한 (function (lambda ...))에 대한 구문 설탕이 있습니다.

Emacs lisp의 함수에 대한 자세한 내용은 Functions info pages을 참조하십시오.

그냥이 모든 것을 확인하기 위해, 당신은 표현하여 * 스크래치 * 버퍼에 다음을 입력하고 평가할 수 : 그래서

(caddr '(lambda (x) (+ x x))) 
(+ x x) 

(caddr (lambda (x) (+ x x))) 
(+ x x) 

(caddr (function (lambda (x) (+ x x)))) 
(+ x x) 

(equal '(lambda (x) (+ x x)) 
     (function (lambda (x) (+ x x)))) 
t 

(equal '(lambda (x) (+ x x)) 
     (lambda (x) (+ x x))) 
t 

을 바로 사용할 수있다 목록을 구축 람다를 사용하는 세 가지 변종 함수 (그 중 하나는 바이트 컴파일 될 수 있음).

+0

그러나 식 앞에 작은 따옴표를 사용하지 않아서 LISP 인터프리터가 현재 값을 반환하고 평가하지 않습니다. 즉, '(+ 1 2)는 (+ 1 2)로 반환되고 (+ 1 2)는 3 ... – Joscha

+0

@Joscha로 반환됩니다. 어떤 부분에 댓글을 달았는지 확실하지 않습니다. 람다는 자기 인용어로 해석기가 람다 식을 평가할 때 그 결과가 동일한 람다식이라는 것을 의미합니다. 나는 Emacs (무한 범위와 동적 범위)에서 사용되는 변수 조회 (lookup) 때문에 다른 리스프 들과는 다르다고 생각한다. Scheme은 어휘 확장으로 인해 일부 환경 정보로 거의 폐쇄되지 않습니다 (필자는 믿습니다). –

+2

'(lambda ...)'는'(macroexpand (lambda ...)')를 평가함으로써 시용 할 수있는''(lambda ...) + xx)))' – nschum

3

음호 (quote (lambda...))(lambda...)은 (바이트 컴파일시) 동일하지 않습니다. 따옴표 붙은 람다는 바이트 컴파일되지 않으며 다른 모든 것은 있습니다. 예를 들어

:

(defun foo (a) 
    (byte-code-function-p a)) 

(defun bar() 
    (foo '(lambda() (ignore 'me)))) 

(defun bar2() 
    (foo (lambda() (ignore 'me)))) 

(defun bar3() 
    (foo (function (lambda() (ignore 'me))))) 

(defun bar4() 
    (foo #'(lambda() (ignore 'me)))) 

(byte-compile 'bar) 
(byte-compile 'bar2) 
(byte-compile 'bar3) 
(byte-compile 'bar4) 

(bar) ; -> nil 

(bar2) ; -> t 
(bar3) ; -> t 
(bar4) ; -> t 

당신은 일반적으로 그냥 funcall보다 그것을 그것으로 뭔가 다른 일을되는 람다를 전달하려고하는 기능을하지 않는 한 람다를 인용하고 싶지 않아요.

+1

나는 이것이 시간이 지남에 따라 변했다고 믿는다. ''info '(elisp) 익명 함수 ")'를 보면,"요즘에는'function '을 완전히 생략 할 수 있습니다 ... 이것은'lambda '자체가'함수 '를 의미하기 때문입니다. " 이 페이지는 첫 번째 읽기에는 다소 혼란 스럽지만 예제를 통해 명확한 설명을 얻습니다. (a)'(function (lambda ...))'는'(quote (lambda ...) 바이트 컴파일을 가능하게합니다. (b) * un * -quoted ((lambda ...))는 (요즘은) (function (lambda ...))와 동일합니다! – phils