Chcę przetestować makro, które używa gensymów. Na przykład, jeśli chcesz przetestować to:Jak przetestować makro clojure, które używa gensymów?
(defmacro m1
[x f]
`(let [x# ~x]
(~f x#)))
mogę użyć makro-ekspansję ...
(macroexpand-1 '(m1 2 inc))
... dostać ...
(clojure.core/let [x__3289__auto__ 2] (inc x__3289__auto__))
To proste aby osoba mogła zweryfikować, że jest poprawna.
Ale jak mogę to przetestować w praktycznym, czystym stylu zautomatyzowanym? Gensym nie jest stabilny.
(Tak, wiem, że zwłaszcza makro przykład nie jest koniecznością, ale pytanie nadal jest fair.)
Zdaję sobie sprawę wyrażenia Clojure mogą być traktowane jako dane (jest to język homoiconic), więc mogę wyciągnąć oprócz wyniku jak ten:
(let [result (macroexpand-1 '(m1 2 inc))]
(nth result 0) ; clojure.core/let
(nth result 1) ; [x__3289__auto__ 2]
((nth result 1) 0) ; x__3289__auto__
((nth result 1) 0) ; 2
(nth result 2) ; (inc x__3289__auto__)
(nth (nth result 2) 0) ; inc
(nth (nth result 2) 1) ; x__3289__auto__
)
Ale to jest nieporęczny. Czy są lepsze sposoby? Być może istnieją biblioteki "sprawdzania poprawności" struktury danych, które mogłyby się przydać? Może destrukturyzacja ułatwiłaby to? Programowanie logiczne?
UPDATE/KOMENTARZ:
Choć doceniam rady doświadczonych ludzi, którzy mówią „nie przetestować sam rozszerzający makra”, to nie odpowiada bezpośrednio na moje pytanie.
Co jest złego w "testowaniu jednostkowym" makra, testując makro-ekspansję? Testowanie rozszerzenia jest uzasadnione - i faktycznie wiele osób testuje swoje makra w ten sposób "ręcznie" w REPL - więc dlaczego nie przetestować go automatycznie? Nie widzę powodu, żeby tego nie robić. Przyznaję, że testowanie makro-ekspansji jest bardziej kruche niż testowanie wyniku, ale robienie tego pierwszego może wciąż mieć wartość. Możesz także przetestować funkcjonalność - możesz zrobić obie! To nie jest żadna z tych decyzji.
Oto moje wyjaśnienie psychologiczne. Jednym z powodów, dla których ludzie nie testują makro-ekspansji, jest to, że obecnie jest to trochę uciążliwe. Ogólnie rzecz biorąc, ludzie często racjonalizują działania, gdy wydaje się to trudne, niezależnie od ich wewnętrznej wartości. Tak - właśnie dlatego zadałem to pytanie! Gdyby to było łatwe, myślę, że ludzie robiliby to częściej. Gdyby było to łatwe, byliby mniej skłonni do racjonalizacji, udzielając odpowiedzi mówiąc, że "nie warto tego robić".
Rozumiem również argument, że "nie powinieneś pisać złożonego makra". Pewnie. Ale miejmy nadzieję, że ludzie nie posuną się aż tak daleko, aby myśleć: "jeśli będziemy zachęcać kulturę nie testowania makr, to uniemożliwi to pisanie złożonych". Taki argument byłby głupi. Jeśli masz złożoną makro-ekspansję, testowanie, że działa zgodnie z oczekiwaniami, jest rozsądną rzeczą do zrobienia. Osobiście nie testuję nawet prostych rzeczy, ponieważ często jestem zaskoczony, że błędy mogą wynikać z prostych błędów.
Dziękuję za chęć wyrażenia "spróbuj innego podejścia". Twoja rada jest z pewnością podzielana przez wielu. Zgadzam się, że testowanie końcowego wyniku jest dobrą strategią. (Ale to nie znaczy, że również testowanie rozszerzenia jest niemądre, myślę, że oba razem dają bardziej wszechstronny test). Na to pytanie chcę przetestować makro-ekspansję. Czy jest to mądre, z pewnością jest dyskusyjne (patrz wyżej). –