2013-07-23 22 views
26

Jestem całkiem nowy w Clojure i nie jestem pewien, czy całkowicie rozumiem różnicę między apostrofem a zwrotem akcji w Clojure.Clojure - różnica między "(apostrof) a" (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. Popraw mnie jeśli się mylę, ale wydaje mi się, że apostrof zapobiega wszystkie symbole (czyli + i x) od rozstrzygnięcia do ich odpowiednich var'S, natomiast lewy apostrof pozwala symbole rozwiązać do ich var użytkownika (ale nie ocenia wartości w var). Czy to jest dokładne?
  2. Co dokładnie robi tutaj symbol nieobecności (~)? Czy wartość zmiennej jest różna od jej rzeczywistej wartości (tj. Symbol + dla obiektu funkcji i symbol x dla obiektu liczby)? Jeśli mógłbyś to wyjaśnić w kategoriach faz CZYTELNEGO CZYNNOŚCI Clojure'a, byłoby to również pomocne.

Odpowiedz

22

Cytując kolekcję z ', nazwa symbolu będzie cytowana dokładnie tak, jak ją podajesz.

'(+ 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") 

Kiedy zacytujesz kolekcję z powrotem, próbuje znaleźć obszar nazw każdego symbolu. Jeśli nie może go znaleźć, używa bieżącego obszaru nazw. Jeśli określisz przestrzeń nazw, działa ona tak samo, jak ' z kwalifikowaną przestrzenią nazw.

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

Kiedy używasz ~ wewnątrz ` formularz będzie po prostu być cytowane. Jest to pomocne przy tworzeniu makr, w których makro używa symboli z przestrzeni nazw, w której jest zdefiniowany, oraz symboli z obszaru nazw, w którym jest używane.

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

Wreszcie możesz zanotować całą kolekcję cytowanych splotów.

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

zobaczyć zarówno x es mogły być przekazywane w formie listy symboli przestrzeni nazw wykwalifikowanych i zostałby wstawiony do innej listy. Nie można użyć ~ ani [email protected] poza zbiorem cytowanej zwrotki.

+1

Dobra odpowiedź. Tutaj znajdziesz świetny wpis na blogu: https://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html –

+1

Zobacz wszystkie przykłady na żywo z 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

Cytat jest cytatem składni w terminologii Clojure, zobacz jego opis pod adresem http://clojure.org/reader.

Podczas czytania, `(~ + ~ x ~ x) rozwija się do postaci, która generuje listę, która może odnosić się do środowiska leksykalnego. Następnie kompilator skompiluje ten kod. Zobaczmy, co `(~ + ~ x ~ x) rozszerza się, poprzedzenie go z cytatem:

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

Jeśli tylko wstawić ten formularz w edytorze tekstu zamiast` (~ + ~ x ~ x), to zbuduje listę z funkcją + i dwoma znakami x. Tak więc, `(~ + ~ x ~ x) rozszerza się do kodu Clojure, który buduje listę konkretnej struktury.

Cofnij to rodzaj szablonu języka dla danych Clojure (listy, tablice itp.).

+0

Co właściwie oznacza "cytat z syntaktyki"? – wmock

+0

To jest tylko słowo w dokumentacji Clojure. Zobacz także http://stackoverflow.com/questions/3704372/how-does-clojures-syntax-quote-work – monoid

+3

oznacza cytat, ale po pierwszym rozwiązaniu symboli: "+ oznacza po prostu" + ", podczas gdy \' + oznacza "clojure.core/+ ', ale jeśli powiedziałeś (def + reszta), to \ '+ staje się użytkownikiem/+' - więc jest tym, na co symbol rozwiązuje w środowisku. – Hendekagon