2011-07-29 26 views
7

Czy można prześledzić zamknięcie w CL? Na przykład, czy mogę prześledzić foo-3 poniżej?Śledzenie zamknięcia

(defun foo (n) 
    (lambda (i) (incf n i))) 
FOO 
(setf foo-3 (foo 3)) 
#<CLOSURE :LAMBDA (I) (INCF N I)> 

(funcall foo-3 2) 
5 
(funcall foo-3 2) 
7 
(trace ???) 
+1

Świetne pytanie! –

Odpowiedz

1

To jest rzeczywiście możliwe, aby to zrobić. Trace szuka funkcji w przestrzeni nazw funkcji, więc nie mieszaj wartości i funkcji.

(setf (symbol-function 'test) 
    (let ((n 0)) 
    (lambda (x) 
    (incf n x)))) 
=> 
#<Interpreted Closure TEST> 
(trace test) 
... 
(test 4) 
=> 
0[2]: (TEST 4) 
0[2]: returned 4 
4 
(test 3) 
=> 
0[2]: (TEST 3) 
0[2]: returned 7 
7 
+0

Dzięki! Przejrzałem http://www.gnu.org/s/emacs/manual/html_node/elisp/Symbol-Components.html#Symbol-Components, http://www.dreamsongs.com/Separation.html i CLTL. Teraz dobrze się z tym czuję. Jakieś inne zasoby na ten temat przestrzeni nazw, które warto przywołać? – user869081

3

Nie sądzę, jest to możliwe: o ile mi wiadomo, makro ślad działa zazwyczaj poprzez zastąpienie funkcji w danym symbolu przez owinięcie że wywołuje również oryginalny i wypisuje trochę śledzenia.

Jeśli są Państwo zainteresowani (skomplikowanymi) szczegółami implementacji, kod SBCL znajduje się pod numerem src/code/ntrace.lisp (najprawdopodobniej zajmiemy się funkcją trace-1).

Oczywiście, jeśli wszystko, co chcesz zrobić, to coś wydrukować, gdy bla-3 jest nazywany, zawsze można umieścić oświadczenie drukowania wewnątrz formy lambda w obu ...

+1

Czy w zamknięciach istnieje coś fundamentalnego, co uniemożliwia pisanie funkcji śledzenia? – user869081

0

myślę tu problem jest że trace wymaga nazwy funkcji, a nie problemu z wykrywaniem zamknięć. Kontynuując z powyższego przykładu, można zadzwonić foo-3 z nazwanego funkcji oraz śladowe że:

(defun call-foo-3 (i) 
    (funcall foo-3 i)) 
(trace call-foo-3) 
(call-foo-3 2) 
    0: (CALL-FOO-3 2) 
    0: CALL-FOO-3 returned 15