2012-02-22 10 views

risposta

18

I termini non sono proprio sinonimi, ma non sono esclusivi o (questa risposta presuppone Scheme):

  • Un forma particolare (noto anche come un sintassi nel report Scheme) è un'espressione che non viene valutata in base alla regola predefinita per l'applicazione di funzione. (La regola di default, tanto per essere espliciti, è quello di eval tutte le sottoespressioni, e quindi apply il risultato del primo alla lista dei risultati degli altri.)
  • Il macro sistema è una caratteristica del linguaggio che consente la definizione di nuove forme speciali all'interno del linguaggio stesso. Una macro è un modulo speciale definito utilizzando il sistema macro.

Così si potrebbe dire che "forma speciale" è un termine che appartiene alla interfaccia o semantica, mentre "macro" è un termine che appartiene alla implementazione. "Forma speciale" significa "queste espressioni sono valutate con una regola speciale", mentre "macro" significa "ecco un'implementazione di una regola speciale per la valutazione di alcune espressioni."

Ora, una cosa importante è che le forme speciali più Scheme possono essere definiti come macro da davvero un piccolo nucleo di primitive: lambda, if e macro Un'implementazione Scheme minima che fornisce solo questi possono ancora implementare il resto come le macro;. i recenti Scheme Reports hanno fatto questa distinzione facendo riferimento a forme speciali come "sintassi di libreria" che possono essere definite in termini di macro.In pratica, tuttavia, i sistemi di Schema pratici implementano spesso un insieme più ricco di forme come primitive

Semanticamente parlando, l'unica cosa che conta su un'espressione è quale regola viene utilizzata per valutarla, non come viene implementata quella regola. Quindi in questo senso, non è importante se una forma speciale è implementata come una macro o una primitiva. D'altra parte, i dettagli di implementazione di un sistema Scheme spesso "perdono", quindi potresti trovarti a occupartene ...

+1

Puoi implementare' if' come macro sopra 'lambda' anche. Non è terribilmente efficiente, ma è una cosa carina da sapere. – amalloy

+0

Sento che questa risposta è la più chiara. Dal momento che definisce 'special-form' secondo la sua semantica - cioè - senza fare affidamento sui dettagli di implementazione. –

+1

@amalloy, sono interessato a come si può fare, hai un collegamento a portata di mano? –

4

A differenza di forme speciali, forme macro può essere macroexpanded:

CL-USER(1): (macroexpand '(with-slots (x y z) 
           foo 
          (format t "~&X = ~A" x))) 

(LET ((#:G925 FOO)) 
    (DECLARE (IGNORABLE #:G925)) 
    (DECLARE (SB-PCL::%VARIABLE-REBINDING #:G925 FOO)) 
    #:G925 
    (SYMBOL-MACROLET ((X (SLOT-VALUE #:G925 'X)) 
        (Y (SLOT-VALUE #:G925 'Y)) 
        (Z (SLOT-VALUE #:G925 'Z))) 
    (FORMAT T "~&X = ~A" X))) 
T 
+0

Ciao Matthias. In tAoAI Norvig afferma che 'setf' è una forma speciale. Tuttavia fa macroexpand. E.g: '(macroexpand '(setf test 4))' si espande in '(SETQ TEST 4)' Forse c'è un errore nel libro? Non vedo 'setf' qui: http://www.lispworks.com/documentation/lw60/CLHS/Body/03_ababa.htm#clspecialops – tsikov

11

Lisp ha alcune primitive di linguaggio, che costituiscono forme Lisp:

  • dati letterali: numeri, stringhe, strutture, ...
  • chiamate di funzione, come (sin 2.1) o simili ((lambda (a b) (+ a b 2)) 3 4)
  • operatori speciali utilizzati in forme speciali. Questi sono i primitivi elementi del linguaggio integrati. Vedi Special Operators in Common Lisp. Questi devono essere implementati nell'interprete e nel compilatore. Common Lisp non consente allo sviluppatore di introdurre nuovi operatori speciali o di fornire la propria versione di questi. Uno strumento di analisi del codice dovrà comprendere questi operatori speciali; questi strumenti sono solitamente chiamati 'code walker' nella comunità Lisp. Durante la definizione dello standard Common Lisp, è stato fatto in modo che il numero fosse molto piccolo e che tutte le estensioni vengano eseguite tramite nuove funzioni e nuovi macro.
  • macro: i macro sono funzioni che trasformano il codice sorgente. La trasformazione avverrà in modo ricorsivo fino a quando non verrà lasciata alcuna macro nel codice sorgente. Common Lisp ha macro integrati e consente all'utente di scriverne di nuovi.

Quindi la differenza pratica più importante tra forme speciali e macro è questa: gli operatori speciali sono sintassi e semantica incorporate. Non possono essere scritti dallo sviluppatore. Le macro possono essere scritte dallo sviluppatore.

4

Per me la differenza più pratica è stata nel debugger: i macro non mostrano su nel debugger; invece, il codice (tipicamente) oscuro dall'espansione della macro appare nel debugger. È un vero problema eseguire il debug di questo codice e una buona ragione per garantire che i tuoi macro siano solidi prima di iniziare a fare affidamento su di essi.

+1

Questa è una preoccupazione se non si dispone di un debugger di macro, ma alcuni Lisp lo fanno effettivamente. Ad esempio, Racket ne possiede uno che è possibile utilizzare anche da [REPL] (http: //docs.racket-lang.org/xrepl/index.html# \ (xrepl._syntax \)). –

2

la risposta super-breve per i più pigri

È possibile scrivere i propri macroes ogni volta che si desidera, anche se è Non è possibile aggiungere forme speciali senza ricompilare clojure.

Problemi correlati