2015-02-02 11 views
5

Ho appena letto sul sharpsign macro lettore di due punti e che sembrava che ha avuto un effetto molto simile a gensymDifferenze tra Sharpsign Colon e gensym

Colon Sharpsign: "introduce un simbolo uninterned"

gensym: "crea e restituisce un simbolo fresco uninterned"

Quindi, un semplice test

CL-USER> #:dave 
; Evaluation aborted on #<UNBOUND-VARIABLE DAVE {1002FF77D3}>. 
CL-USER> (defparameter #:dave 1) 
#:DAVE 
CL-USER> #:dave 
; Evaluation aborted on #<UNBOUND-VARIABLE DAVE {100324B493}>. 

Freddo in modo che non riesca come dovrebbe.

Ora per la prova di macro

(defmacro test (x) 
    (let ((blah '#:jim)) 
    `(let ((,blah ,x)) 
     (print ,blah)))) 

CL-USER> (test 10) 

10 
10 
CL-USER> 

dolce in modo che possa essere utilizzato come in una sorta di modo gensym.

Per me sembra più pulito di gensym con un risultato apparentemente identico. Sono sicuro che mi manca un dettaglio fondamentale quindi la mia domanda è: di cosa si tratta?

risposta

6

GENSYM è come MAKE-SYMBOL. La differenza è che GENSYM supporta la denominazione di fantasia effettuando il conteggio -> quindi i tipi di simboli hanno nomi univoci, il che rende il debug un po 'più semplice quando si hanno gensyms per esempio nelle espansioni di macro.

#:foo è una notazione per il lettore.

Quindi si dispone di una funzione che crea queste e una notazione letterale. Si noti che, quando *print-circle* è true, un tipo di identità può essere conservato nelle espressioni s: #(#1=#:FOO #1#).

Generalmente questo è simile a (a . b) e (cons 'a 'b), #(a b) e (vector 'a 'b) ... Uno è dato letterale e l'altro è una forma che creerà ('') cons freschi oggetti.

Se si guarda la tua macro, il problema principale è che l'uso annidato di esso potrebbe causare problemi. Sia lessicalmente che dinamicamente.

  • in modo lessicale potrebbe essere la stessa variabile, che è il rimbalzo.

  • dinamicamente, se si tratta di una variabile speciale potrebbe anche essere rimbalzo

Utilizzando un simbolo generato in fase di espansione macro sarebbe fare in modo che il codice diverso e ampliato, non avrebbe condiviso attacchi.

+0

Oh sì, non avevo passato tempo a pensare alle implicazioni di cattura, che ovviamente l'intero punto ... due! Grazie per questo – Baggers

8

Ogni volta che la macro viene espansa, utilizzerà lo stesso simbolo.

Gensym creerà un nuovo simbolo ogni volta che viene valutato, ma i due punti marcati creeranno un nuovo simbolo solo quando viene letto.

Anche se l'uso di due punti non causa problemi, ci sono un paio di rari casi in cui l'utilizzo di questo strumento potrebbe portare a errori quasi impossibili.Innanzitutto è meglio essere sicuri usando sempre gensym.

Se si desidera utilizzare qualcosa come il colon nitido, è necessario esaminare la macro defmacro! da Let Over Lambda.

+0

inchiodato, ero un manichino per non pensare alla cattura. Ho persino letto laggiù lambda, quindi oggi ero davvero un airhead – Baggers