2012-01-03 16 views
7

Ci scusiamo per il titolo terribilmente vaghi :)Clojure - Citando Confusione

Sono nuovo di macro e sto avendo difficoltà a capire la differenza tra queste due affermazioni:

`(+ 1 2 ~(+ 2 3)) ; => (clojure.core/+ 1 2 5) 
'(+ 1 2 ~(+ 2 3)) ; => (+ 1 2 (clojure.core/unquote (+ 2 3))) 

Quando li ho eseguito senza l'unquote , sembrano piuttosto identici a parte le qualifiche?

`(+ 1 2 (+ 2 3)) ; => (clojure.core/+ 1 2 (clojure.core/+ 2 3)) 
'(+ 1 2 (+ 2 3)) ; => (+ 1 2 (+ 2 3)) 

Quindi in pratica sono confuso da "vs". La mia comprensione è che entrambi citano tutto nella lista, ed è per questo che non sono sicuro del perché la unquotazione si comporti diversamente. Fondamentalmente `si comporta come mi aspetterei che sia 'che' si comportino.

Grazie!

risposta

10

La risposta breve è che lo smascheramento funziona solo all'interno di un backquote. In un'espressione quotata normale, tutto, incluso ~ e tutto ciò che è dentro/dietro, viene passato così com'è, mentre all'interno di un'espressione racchiusa viene valutato tutto ciò che si trova all'interno/dietro ~ (ma tutto il resto rimane non valutato). Quindi, no, non tutto ciò che si trova all'interno di un'espressione di backquoted rimane non valutato - puoi usare ~ al suo interno, per usarlo come una specie di modello, dove "riempi gli spazi" con ~.

Modifica: Per citazione (gioco di parole) la documentation relativo alla tua domanda:

Citazione:

Quote (') 
'form => (quote form) 

e (dalla sezione special forms):

(modulo preventivo) Resa la forma non valutata.

user=> '(a b c) 
(a b c) 

Nota non v'è alcun tentativo fatto per chiamare la funzione a. Il valore restituito è un elenco di 3 simboli.

Sintassi-preventivo (chiamato anche quasiquote, backquote):

Per liste/vettori/insiemi/mappe, sintassi preventivo stabilisce un modello di struttura dati corrispondente. All'interno del modello, i moduli non nominati si comportano come se fossero sintassi ricorsiva, ma i moduli possono essere esentati da tale quotazione ricorsiva qualificandoli con unquote o unquote-splicing, nel qual caso verranno considerati come espressioni e sostituiti in il modello in base al loro valore o sequenza di valori, rispettivamente .

+1

Si potrebbe anche parlare della grande carta [Quotazione Quasi in Lisp da Alan Bawden] (http://www.scribd.com/doc/47702904/Bawden-Quasi-Quotation-in-Lisp). – Daimrod

+0

Daimrod, sì, grazie per il link! (Nota per i principianti: ci sono alcune differenze tra gli altri dialoghi Lisp e Clojure.Ad esempio, in CL e nel foglio, ',' (spazio bianco in Clojure) viene usato per non quotare. Inoltre, in CL, un ',' all'esterno di un l'espressione backquoted non è valida (in genere un errore del lettore).) – danlei

+0

Grazie, non mi sono reso conto che lo smascheramento era riservato per la sintassi-citazione. Questo spiega sicuramente i risultati. Sto attraversando Joy of Clojure e mi sono soffermato nel capitolo Macro per sperimentare e provare a capire questa roba, quindi è possibile che abbia perso le spiegazioni più avanti nel capitolo :) – anonymous

4

Provare a eseguire eval sui risultati delle prime due espressioni. Il primo, con "," si espande a (+ 1 2 3), che valuta bene a 6. Il secondo, con "," si espande "a (+ 1 2 (unquote (+ 1 2))) e unquote non è valido in quel contesto poiché non si è più all'interno di una citazione! Quindi questo completamente non riesce a valutare affatto.

Fondamentalmente ci sono due differenze tra 'e':

  • `namespace-qualifica tutto
  • ` permette toglie la quotatura