2013-08-29 8 views
7

Ostatnio dużo myślałem o podstawach Lispa; Czytałem kilka podręczników i/lub innych materiałów w Internecie, w tym The Roots of Lisp P. Graham:Dlaczego nie ma prymitywu Lisp nieokreślonego?

W Korzenie Lisp, quote jest opisany jako prymitywne, że kod do zmiany danych, a tym samym cytowanie to, ale nie ma odpowiednika odwrotnej pierwotnej, czyli prymitywu unquote. Myślałem, że może to być firma eval, ale eval często uruchamia dane w pustym środowisku leksykalnym, co nie jest równoznaczne ze zmianą danych z powrotem do kodu.

Ergo, dlaczego nie ma prymitywu Lisp w wersji unquote?

+2

Rereading swoje pytanie, mam wrażenie, że to, co chcesz, nie jest 'unquote' per se (co jest już przewidziane, jak już wspomniałem w mojej odpowiedzi), ale to rodzaj [ 'local-eval'] (http://www.gnu.org/software/guile/manual/html_node/Local-Evaluation.html), który działa tak samo, jak" eval "JavaScript (w którym dostępne są zmienne leksykalne). –

+1

@ ChrisJester-Young Tak, właśnie o to mi chodzi. – SaltyEgg

+0

@ ChrisJester-Young A ja chcę wiedzieć, dlaczego ten rodzaj "cytatu" nie jest prymitywny. Ponieważ był "cytat", dlaczego autor nie zawarł swojej funkcji odwrócenia? – SaltyEgg

Odpowiedz

8

unquote jest przydatna tylko w kontekście quasiquote i quasiquote mogą być realizowane jako makro (który używa quote za kulisami). Nie ma więc potrzeby prymitywu unquote; makro quasiquote zajmuje się po prostu symbolami unquote, ponieważ zostały znalezione.

(quasiquote jest nazwą Program dotyczący grawis cytatem Zatem:.

`(foo bar ,baz) 

jest odczytywany jako

(quasiquote (foo bar (unquote baz))) 

na schemacie.)


Oto bardzo prosty Schemat quasiquote makro (obsługuje tylko listy, w przeciwieństwie do standardu quasiquote który obsługuje również wektory i inne typy danych)

(define-syntax quasiquote 
    (syntax-rules (unquote unquote-splicing) 
    ((quasiquote (unquote datum)) 
    datum) 
    ((quasiquote ((unquote-splicing datum) . next)) 
    (append datum (quasiquote next))) 
    ((quasiquote (datum . next)) 
    (cons (quasiquote datum) (quasiquote next))) 
    ((quasiquote datum) 
    (quote datum)))) 

Equivalent wersję przy użyciu wszystkich standardowych skrótów czytelnika:

(define-syntax quasiquote 
    (syntax-rules (unquote unquote-splicing) 
    (`,datum 
    datum) 
    (`(,@datum . next) 
    (append datum `next)) 
    (`(datum . next) 
    (cons `datum `next)) 
    (`datum 
    'datum))) 
+0

Makra są rozszerzane przed wykonaniem środowiska wykonawczego, a ten rodzaj nieważności nie ma wpływu na symbol w środowisku wykonawczym. – SaltyEgg

+0

To na Schemacie, gdzie makra działają nie tylko na symbole, ale na identyfikatorach oznaczonych leksykalnymi informacjami. (Yay higieniczne makra!) O ile nie ma konkretnego przykładu, w którym według ciebie mój przykład nie jest odpowiednio adresowany. –

+0

Nie jestem zaznajomiony ze Scheme, testowałem sprawę w Common Lisp, i to nie działa. – SaltyEgg

0

Jestem również stosunkowo nowy Lisp, ale myślę, że to, co można było myśleć jest to eval. eval to sposób na zmianę danych z powrotem na kod.

Mianowicie, należy rozważyć prostą funkcję.

(defun foo (a b c) (list a b c)) 

Następnie, jeśli coś jak to zrobić, można uzyskać listę symboli:

CL-USER> (foo 'a 'b 'c) 
(A B C) 

Jeśli dodać cytatów z przodu, funkcja nazywać się jest traktowana jako element danych (lista):

CL-USER> '(foo 'a 'b 'c) 
(FOO 'A 'B 'C) 

Dodanie jeszcze jednego cytatu ma oczekiwany efekt:

CL-USER> ''(foo 'a 'b 'c) 
'(FOO 'A 'B 'C) 

Teraz rozwińmy to za pomocą eval, która w gruncie rzeczy może być uważana za operację odwrotną dla quote. Jest to odwrotność. Oś X to formularz danych. Oś Y to forma kodu. Mam nadzieję, że ta (nieco rozciągnięta) analogia ma sens.

CL-USER> (eval ''(foo 'a 'b 'c)) 
(FOO 'A 'B 'C) 

Czy możesz zgadnąć, co się stanie, jeśli połączę dwa rzędy z rzędu eval? Oto ona:

CL-USER> (eval (eval ''(foo 'a 'b 'c))) 
(A B C) 
Powiązane problemy