은 가정하자 나는이 빈약 샘플 같은 정원 - 다양한 폐쇄가 어딘가에 (해시 테이블에서). 그럼 난 잠시 동안 (funcall)
이 인스턴스를하지 않습니다. 그런 다음 해시 테이블에서이 인스턴스를 검색하고 반환 된 값 4를 반환하여 (funcall)
을 다시 검색합니다.클로저가 어떻게 자체를 참조 할 수 있습니까?</p> <pre><code>(let ((alpha 0) #| etc. |#) (lambda() (incf alpha) #| more code here |# alpha)) </code></pre> <p>한다고 가정 내가 <code>(funcall)</code>이 폐쇄 3 회 예, 세 번째 실행의 중간에, 이것은 폐쇄 자체를 저장하고 싶어 :
클로저의 함수가 자체를 참조하여 해시 테이블에 저장되는 방식은 무엇입니까?
편집 1 : 다음은 좀 더 자세한 예입니다. 클로저를 매개 변수로 전달하여 목표를 달성합니다. 그러나 클로저가 자기 매개 변수화없이이 모든 것을 자체적으로 수행하고 싶습니다.
1 (defparameter *listeriosis* nil)
2 (defparameter *a*
3 (lambda()
4 (let ((count 0))
5 (lambda (param1 param2 param3 self)
6 (incf count)
7 (when (= 3 count)
8 (push self *listeriosis*)
9 (push self *listeriosis*)
10 (push self *listeriosis*))
11 count))))
12 (let ((bee (funcall *a*)))
13 (princ (funcall bee 1 2 3 bee)) (terpri)
14 (princ (funcall bee 1 2 3 bee)) (terpri)
15 (princ (funcall bee 1 2 3 bee)) (terpri)
16 (princ (funcall bee 1 2 3 bee)) (terpri)
17 (princ (funcall bee 1 2 3 bee)) (terpri))
18 (princ "///") (terpri)
19 (princ (funcall (pop *listeriosis*) 1 2 3 nil)) (terpri)
20 (princ (funcall (pop *listeriosis*) 1 2 3 nil)) (terpri)
21 (princ (funcall (pop *listeriosis*) 1 2 3 nil)) (terpri)
1
2
3
4
5
///
6
7
8
편집 2 : 네, 나는 그것의 첫 번째 매개 변수에 함수의 이름을 미끄러 다음 (funcall)
대신이 매크로를 사용하는 매크로를 사용할 수 있습니다 알고 있지만 나는 아직도 방법을 알고 싶습니다 클로저가 자신의 인스턴스를 참조하도록합니다.
편집 3 : SK 로직의 친절한 제안에 따라 다음을 수행했지만 원하는대로하지 않았습니다. 스택에 3 개의 새로운 클로저를 푸시하지만 동일한 클로저에 대한 세 개의 참조는 푸시하지 않습니다. 스택에서 꺼낼 때 호출 값이 6, 7 및 8 대신 1, 1 및 1 인 방법을 확인하십시오.
1 (defparameter *listeriosis* nil)
2 (defun Y (f)
3 ((lambda (x) (funcall x x))
4 (lambda (y)
5 (funcall f (lambda (&rest args)
6 (apply (funcall y y) args))))))
7 (defparameter *a*
8 (lambda (self)
9 (let ((count 0))
10 (lambda (param1 param2 param3)
11 (incf count)
12 (when (= 3 count)
13 (push self *listeriosis*)
14 (push self *listeriosis*)
15 (push self *listeriosis*))
16 count))))
17 (let ((bee (Y *a*)))
18 (princ (funcall bee 1 2 3 #| bee |#)) (terpri)
19 (princ (funcall bee 1 2 3 #| bee |#)) (terpri)
20 (princ (funcall bee 1 2 3 #| bee |#)) (terpri)
21 (princ (funcall bee 1 2 3 #| bee |#)) (terpri)
22 (princ (funcall bee 1 2 3 #| bee |#)) (terpri))
23 (princ "///") (terpri)
24 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
25 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
26 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
1
2
3
4
5
///
1
1
1
편집 4 : Jon O의 제안이 정확하게 기록되었습니다.
1 (defparameter *listeriosis* nil)
2 (defparameter *a*
3 (lambda()
4 (let ((count 0))
5 (labels ((self (param1 param2 param3)
6 (incf count)
7 (when (= 3 count)
8 (push (function self) *listeriosis*)
9 (push (function self) *listeriosis*)
10 (push (function self) *listeriosis*))
11 count))
12 (function self)))))
13 (let ((bee (funcall *a*)))
14 (princ (funcall bee 1 2 3)) (terpri)
15 (princ (funcall bee 1 2 3)) (terpri)
16 (princ (funcall bee 1 2 3)) (terpri)
17 (princ (funcall bee 1 2 3)) (terpri)
18 (princ (funcall bee 1 2 3)) (terpri))
19 (princ "///") (terpri)
20 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
21 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
22 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
1
2
3
4
5
///
6
7
8
편집 5 : MIRON의 제안도 마크 안타, 실제로 좀 더 읽을 수있는 코드를 만들어 다음은 코드와 출력의
1 (defmacro alambda (parms &body body)
2 `(labels ((self ,parms ,@body))
3 #'self))
4 ;
5 (defparameter *listeriosis* nil)
6 (defparameter *a*
7 (lambda()
8 (let ((count 0))
9 (alambda (param1 param2 param3)
10 (incf count)
11 (when (= 3 count)
12 (push #'self *listeriosis*)
13 (push #'self *listeriosis*)
14 (push #'self *listeriosis*))
15 count))))
16 ;
17 (let ((bee (funcall *a*)))
18 (princ (funcall bee 1 2 3)) (terpri)
19 (princ (funcall bee 1 2 3)) (terpri)
20 (princ (funcall bee 1 2 3)) (terpri)
21 (princ (funcall bee 1 2 3)) (terpri)
22 (princ (funcall bee 1 2 3)) (terpri))
23 (princ "///") (terpri)
24 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
25 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
26 (princ (funcall (pop *listeriosis*) 1 2 3)) (terpri)
1
2
3
4
5
///
6
7
8
당신은 "익명 함수"를 의미한다. 어쨌든, 나는 왜 당신이 단순히 그 이름을 말하지 않을 것이라고 생각하지 않습니까? – delnan
나는 클로저의 새로운 인스턴스를 원하지 않는다. 내가 둘러싼 변수를 계속 변경하면서 오래된 것을 원한다. 실제로, 여러 인스턴스가있을 수 있으며, 각 인스턴스는 어딘가에서 소금으로 처리되어야합니다. 이름을 밝히면서이 모든 작업을 수행 할 수 있습니까? 문법은 무엇입니까? –
나는 lisp을 아주 잘 말하지 않지만 JavaScript에서 흔히 볼 수있는 "self-executing function expressions"같은 것이이 트릭을 수행한다고 가정합니다. – delnan