2013-07-02 12 views
7

Nel contesto della scrittura di macro Racket, cosa significa "sintassi 3D"?Che cos'è la "sintassi 3D"?

Ho sentito la frase alcune volte. Includendo una volta in riferimento a una macro I scriveva. Ma è passato un po 'di tempo fa; L'ho risolto e ora non riesco a ricordare esattamente cosa stavo sbagliando in origine.

Inoltre: la sintassi 3D è sempre errata? O è come eval (dove se pensi di aver bisogno di usarlo, probabilmente hai torto, ma ci sono alcuni usi validi in mani esperte)?

+0

In futuro, forse tutto sarà ben documentato! +1 per la difficoltà. Sembra una buona domanda di taglia per me. L'unica cosa che ho potuto localizzare in modo rilevante è stata questa discussione: http://lists.racket-lang.org/dev/archive/2013-January/011637.html – jdero

risposta

6

Si suppone che gli oggetti di sintassi siano solo serializable data. La sintassi 3D indebolisce questa condizione: ci permette di intrufolarsi in valori arbitrari e non solo in semplici dati. Questo è ciò che li rende "3d": sono valori che si elevano al di sopra delle normali cose piatte che ci si aspetterebbe da oggetti di sintassi.

Ad esempio, possiamo introdurre nei valori lambda!

#lang racket 

(define ns (make-base-namespace)) 
(define (set-next! n) 
    (parameterize ([current-namespace ns]) 
    (eval #`(define next #,n)))) ;; <-- 3d-syntax here 

(define (compute s) 
    (parameterize ([current-namespace ns]) 
    (eval s))) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
(define counter 0) 
(set-next! (lambda() 
      (set! counter (add1 counter)) 
      counter)) 

(compute '(+ (next) 
      (next) 
      (next) 
      (next))) 

fare questo è di solito una cosa negativa, perché la presenza di tali valori significa probabilmente un tentativo mal fondata a trapelare informazioni attraverso le fasi di compilazione. Il risultato è qualcosa che probabilmente non è compilabile separatamente. Se viene visualizzato un errore che suona qualcosa come:

write: cannot marshal value that is embedded in compiled code value 

allora questo è molto probabilmente a causa di una macro avendo prodotto un pezzo di 3d-sintassi che non può essere serializzato in bytecode.

A volte, in rare situazioni, vogliamo davvero la sintassi 3d, spesso in contesti di valutazione dinamica. Come esempio concreto, un debugger in DrRacket potrebbe voler annotare la sintassi di un programma in modo che le applicazioni di funzione richiamino direttamente le funzioni del debugger, in modo che possiamo fare cose come la colorazione della copertura del codice interattivo nell'editor del programma. In questo senso, la sintassi 3d può fungere da canale di comunicazione tra il codice valutato dinamicamente e il suo ambiente ambientale.

+0

anche in contesti come quello, anche se sembra più pulito iniettare la funzione come una dipendenza a livello di modulo, in qualche modo. Comunque, um, lo stepper è pieno di sintassi 3d. –

+0

concordato. Ma mi sono imbattuto in alcuni strani problemi cercando di farlo: http://lists.racket-lang.org/dev/archive/2013-April/012126.html, e sfortunatamente non ho tempo in questi giorni per capire cosa esattamente mi manca – dyoo

+1

Per prima cosa, grazie per aver risposto! Ho riletto, pensato e sto cercando di capire come rispondere. Per prima cosa, ho pensato che la risposta avrebbe comportato parlare di trasformatori di sintassi, ma tu stai usando eval e namespace, e sto cercando di pensare a cosa significhi. Inoltre, sono confuso e/o distratto dall'uso dei namespace nel tuo esempio, e sto cercando di capire se ciò è essenziale e, in tal caso, come/perché. [Questo] (https://gist.github.com/greghendershott/5923364) è più semplice. Dà la stessa risposta: 10. È equivalente o no? –

Problemi correlati