2013-07-23 14 views
26

Sono abbastanza nuovo per Clojure e non sono sicuro di comprendere completamente la differenza tra l'apostrofo e il backtick in Clojure.Clojure - differenza tra '(apostrofo) e `(backtick)

(def x 5) 

;; Question 1 
(+ x x) ;; evaluates to 10 
'(+ x x) ;; evaluates to (+ x x) 
`(+ x x) ;; evaluates to (clojure.core/+ user/x user/x) 

;; Question 2 
`(~+ ~x ~x) ;; evaluates to (#<core$_PLUS_ [email protected]> 5 5) 
  1. Correggetemi se sbaglio, ma mi sembra che apostrofo impedisce tutti i simboli (cioè + e x) da risolvere alla loro rispettiva var di, mentre backtick permette i simboli di risolvere al proprio VAR (ma non valuta i valori all'interno della var). È accurato?
  2. Che cosa fa esattamente il simbolo unquote (~) qui? Sta valutando la var al suo valore reale (cioè il simbolo + per l'oggetto funzione e il simbolo x per l'oggetto numero)? Se potessi spiegare questo in termini di fasi READ-COMPILE-EVAL di Clojure, sarebbe altrettanto utile.

risposta

22

Quando si cita una raccolta con ', il nome-simbolo sarà citato esattamente come viene inserito.

'(+ x x) 
=> (+ x x) 
(map namespace *1) 
=> (nil nil nil) 
'(bingo/+ lara/y user/z) 
=> (bingo/+ lara/y user/z) 
(map namespace *1) 
=> ("bingo" "lara" "user") 

Quando si cita una collezione con il backtick, si cerca di trovare spazio dei nomi di ogni simbolo. Se non riesce a trovarne uno, usa lo spazio dei nomi corrente. Se si specifica uno spazio dei nomi, funziona come ' con uno spazio dei nomi qualificato.

`(+ x x) 
= > (clojure.core/+ user/x user/x) 
(map namespace *1) 
=> ("clojure.core" "user" "user") 

Quando si utilizza ~ all'interno ` forma sarà semplicemente non quotate. Ciò è utile per la creazione di macro in cui la macro utilizza simboli dallo spazio dei nomi in cui è definita così come i simboli dallo spazio dei nomi in cui viene utilizzato.

`(+ ~'x x) 
=> (clojure.core/+ x user/x) 
`(+ ~x x) 
=> (clojure.core/+ 3 user/x) 

Infine, è possibile unquote un'intera collezione di cose citato splicing.

`(+ [email protected]`(x x)) 
=> (clojure.core/+ user/x user/x) 

vedere sia x es avrebbero potuto essere passato come un elenco di simboli namespace-qualificati e sarebbero stati impiombato in un'altra lista. Non è possibile utilizzare ~ o [email protected] al di fuori di una raccolta citata con apice.

+1

Bella risposta. C'è un post sul blog eccellente qui se vuoi approfondire: https://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html –

+1

Vedi tutti quegli esempi in diretta con KLIPSE http: //app.klipse.tech/?cljs_in=(ns%20my.ns)%0A%0A%5B%0A%20%20' (% 2B% 20x% 20x)% 20% 0A% 20% 20% 60 (% 2B% 20x% 20x)% 0A% 20% 20% 60 (~ '% 2B% 20x% 20x)% 0A% 20% 20% 60 (% 2B% 20 ~% 40% 60 (% 2B% 20x% 20x))% 0A% 5D% 0A – viebel

2

Backquote è una citazione di sintassi in termini Clojure, vedere la relativa descrizione allo http://clojure.org/reader.

Durante la lettura, `(~ + ~ x ~ x) si espande per formare quello che genera la lista che può riferirsi all'ambiente lessicale. Quindi il compilatore compila questo codice. Vediamo cosa `(~ + ~ x ~ x) si espande a, anteponendo con una citazione:

user=> '`(~+ ~x ~x) 
(clojure.core/seq (clojure.core/concat (clojure.core/list +) (clojure.core/list x) (clojure.core/list x))) 

Se è sufficiente inserire il modulo in editor di testo invece di` (~ + ~ x ~ x), si costruirà una lista con + funzione e due x. Quindi, `(~ + ~ x ~ x) si espande nel codice Clojure che crea un elenco di strutture particolari.

Backquote è un tipo di linguaggio modello per i dati Clojure (elenchi, matrici, ecc.).

+0

Che cosa significa "sintassi-preventivo" in realtà? – wmock

+0

È solo una parola nella documentazione di Clojure. Vedi anche http://stackoverflow.com/questions/3704372/how-does-clojures-syntax-quote-work – monoid

+3

significa citazione, ma avendo prima risolto i simboli: '+ significa solo' + ', mentre \ '+ significa 'clojure.core/+ ', ma se hai detto (def + rest), quindi \ '+ diventa' user/+ '- quindi è quello che il simbolo risolve nell'ambiente – Hendekagon

Problemi correlati