Dalla mia esperienza, le macro danno la migliore impressione alle persone quando vedono come aiuta a produrre codice, che non può essere fatto dalle procedure o da altri costrutti. Molto spesso queste cose possono essere descritti come:
<common code>
<specific code>
<other common code>
dove <common code>
è sempre lo stesso. Ecco alcuni esempi di questo schema:
1. La macro time
. codice in un linguaggio senza macro sarà simile a questo:
int startTime = getCurrentTime();
<actual code>
int endTime = getCurrentTime();
int runningTime = endTime - startTime;
Non si può mettere tutto il codice comune a procedimento, dal momento che avvolge codice vero e proprio giro. (OK, puoi eseguire una procedura e passare il codice effettivo nella funzione lambda, se la lingua lo supporta, ma non è sempre conveniente).
E, come probabilmente sapete, in Lisp basta creare time
macro e passare codice vero e proprio ad esso:
(time
<actual code>)
2. transazioni. Chiedere al programmatore Java di scrivere il metodo per semplice SELECT
con JDBC - occorreranno 14-17 linee e includere il codice per aprire la connessione e la transazione, per chiuderle, diverse istruzioni nidificate try-catch-finally
e solo 1 o 2 righe di codice univoco.
In Lisp è sufficiente scrivere la macro with-connection
e ridurre il codice a 2-3 righe.
3. Sincronizzazione. OK, Java, C# e la maggior parte dei linguaggi moderni hanno già delle istruzioni per questo, ma cosa fare se il tuo linguaggio non ha un simile costrutto? O se vuoi introdurre un nuovo tipo di sincronizzazione come le transazioni basate su STM? Ancora una volta, dovresti scrivere una classe separata per questa attività e lavorarci manualmente, cioè inserire un codice comune attorno a ogni istruzione che desideri sincronizzare.
Questi erano solo alcuni esempi. Puoi menzionare macro "non dimenticabili" come la serie with-open
, quell'ambiente di pulizia e proteggerti da perdite di ricorsi, nuove macro di costrutto come cond
invece di più if
s e, naturalmente, non dimenticare i costrutti pigri come if
, or
e and
, che non valutano i loro argomenti (in opposizione all'applicazione della procedura).
Alcuni programmatori possono sostenere che la loro lingua ha una tecnologia per trattare questo o quel caso (ORM, AOP, ecc.), Ma chiedete loro, sarebbero necessarie tutte queste tecnologie, se esistessero macro?
Quindi, prendendolo del tutto e rispondendo alla domanda originale su come spiegare i macro. Prendi un codice largamente usato in Java (C#, C++, ecc.), Trasformalo in Lisp e poi riscrivilo come macro.
Correlato: http://stackoverflow.com/questions/267862/what-makes-lisp-macros-so-special – jball
Penso che una delle migliori introduzioni alle macro sia in [Practical Common Lisp] (http: // gigamonkeys.com/book/practical-a-simple-database.html). È uno dei primi capitoli, quindi non assume troppo, e non è così lungo. L'intero libro è fantastico, altamente raccomandato per chiunque, programmatore "generico" o meno (ci sono anche capitoli sulla programmazione generica!). – spacemanaki