Przykład makra when w Clojure:(defmacro when [test & body] (list 'if test (cons 'do body)))Powyższe makro działa podobnie do konstrukcji sterującej if, ale ma tylko jedną „odnogę” i można do niej wstawiać wiele wyrażeń. Zapisanie tego kodu w postaci funkcji wywołałoby zarówno warunek, jak i ciało.
Warto zauważyć, że lispowe makra są specyficznymi funkcjami, jednak różnią się od zwykłych funkcji następującymi cechami:
Ich podprogramy uruchamiane są zanim dojdzie do uruchomienia programu, a po wczytaniu S-wyrażeń kodu źródłowego, w fazie zwanej makroekspansją. Ich argumenty nie są zachłannie wartościowane przed przekazaniem, lecz ich wartości zawierają podstawiony w miejscach ich przekazania kod źródłowy w postaci struktur danych reprezentujących S-wyrażenia. Zwracane przez nie wartości będą potraktowane jak kod źródłowy, który wstawiony zostanie w miejscach ich wywołań, a następnie poddany procesowi wartościowania wraz z całym programem.
Introspekcja i Refleksja
Są to cechy meta programowania umożliwiające sprawdzanie jak wyglądają obiekty w pamięci np. sprawdzenie listy pól i metod w obiekcie czy pobranie i wywołanie metody, na podstawie wygenerowanego ciągu znaków.
Magiczne metody