2010-09-21 13 views
7

Czy można napisać makro w Clojure, które generuje więcej niż jedną wartość lub wyrażenie? Dla mnie wygląda na to, że nie jest to możliwe, przynajmniej nie za pomocą szablonu cytatu składni `(..).Jak napisać makro Clojure, aby utworzyć więcej niż jedno wyrażenie?

np. od: [1 4] poprzez [1 (mr 2 3) 4] do [1 2 3 4]

lub od:

(do 
    (prn 1) 
    (prn 4)) 

poprzez:

(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4)) 

do:

(do 
    (prn 1) 
    (prn 2) 
    (prn 3) 
    (prn 4)) 

Odpowiedz

10

Makro rozszerza jednej formy w inną formę, więc nie może mieć makra zwracającego dwa całkowicie niezależne f orms. Możesz jednak zwrócić formularze złożone, takie jak do, które zawierają wiele rzeczy.

(defmacro foo [n] 
    `(do [email protected](map #(list println %) n))) 

Dla powyższego przykładu można umieścić makro wokół postaci chcesz zmodyfikować:

(expand-mr 
(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4))) 

makra są zaprojektowane, aby być bezpieczne i jako takie nie mogą modyfikować niczego poza własnym zakres. Obecnie makro dostaje s-wyrażenia i zmienia je w inne użyteczne lub pomocne s-wyrażenie. Aby makro mogło zwrócić dwa oddzielne wyrażenia s, musiałoby zmodyfikować swoje wyrażenie zamykające. Składnia musiałaby być radykalnie odmienna i nie wiem, w jaki sposób można by to zrobić za pomocą wyrażeń s. Rozwiązaniem tego jest rozszerzenie zakresu makra, aby uwzględnić wszystko, co trzeba zmodyfikować.

+0

Dzięki Arthur! Już oczekiwałem tej odpowiedzi, ale miło jest być pewnym. – Stefan

+0

Ale czy możesz podać przykład, w jaki sposób makro zwracające dwie niezależne formy może spowodować problem z bezpieczeństwem, ale czy jest bezpieczny w przeciwnym razie? Myślę, że zakres jest wciąż taki sam. – Stefan

+0

Używam określenia "bezpieczny", bardzo przykro z tego powodu. Będę edytować, aby rozwinąć to. –

Powiązane problemy