Inilah yang saya gunakan untuk debugging (di Clojure):
user=> (defmacro print-var [varname] `(println ~(name varname) "=" ~varname))
#'user/print-var
=> (def x (reduce * [1 2 3 4 5]))
#'user/x
=> (print-var x)
x = 120
nil
Saya harus berurusan dengan tabel hash linting tangan di C + +, di mana get
metode mengambil referensi string non-const sebagai argumen, yang berarti saya tidak bisa menyebutnya dengan literal. Untuk membuatnya lebih mudah untuk ditangani, saya menulis sesuatu seperti berikut:
#define LET(name, value, body) \
do { \
string name(value); \
body; \
assert(name == value); \
} while (false)
Sementara sesuatu seperti masalah ini tidak mungkin muncul di lisp, saya merasa sangat baik bahwa Anda dapat memiliki makro yang tidak mengevaluasi argumen mereka dua kali, misalnya dengan memperkenalkan pengikatan nyata . (Diakui, di sini saya bisa mengatasinya).
Saya juga menggunakan cara membungkus barang yang jelek dan jelek do ... while (false)
sehingga Anda bisa menggunakannya di bagian waktu dan jika masih ada bagian lain seperti yang diharapkan. Anda tidak memerlukan ini dalam lisp, yang merupakan fungsi dari makro yang beroperasi pada pohon sintaks daripada string (atau urutan token, saya pikir, dalam kasus C dan C ++) yang kemudian menjalani parsing.
Ada beberapa makro threading bawaan yang dapat digunakan untuk mengatur ulang kode Anda sehingga terbaca lebih bersih ('threading' seperti dalam 'menabur kode Anda bersama-sama', bukan paralelisme). Sebagai contoh:
(->> (range 6) (filter even?) (map inc) (reduce *))
Ia mengambil bentuk pertama (range 6)
,, dan menjadikannya argumen terakhir dari bentuk berikutnya (filter even?)
,, yang pada gilirannya dijadikan argumen terakhir dari bentuk berikutnya dan seterusnya, sehingga di atas akan ditulis ulang menjadi
(reduce * (map inc (filter even? (range 6))))
Saya pikir yang pertama berbunyi lebih jelas: "ambil data ini, lakukan ini, lalu lakukan itu, lalu lakukan yang lain dan kita selesai", tapi itu subjektif; sesuatu yang secara objektif benar adalah bahwa Anda membaca operasi dalam urutan yang mereka lakukan (mengabaikan kemalasan).
Ada juga varian yang menyisipkan bentuk sebelumnya sebagai argumen pertama (bukan terakhir). Satu kasus penggunaan adalah aritmatika:
(-> 17 (- 2) (/ 3))
Dibaca sebagai "ambil 17, kurangi 2 dan bagi 3".
Berbicara tentang aritmatika, Anda dapat menulis makro yang tidak menguraikan notasi parsing, sehingga Anda bisa mengatakan misalnya (infix (17 - 2) / 3)
dan itu akan memuntahkan (/ (- 17 2) 3)
yang memiliki kelemahan yaitu kurang dapat dibaca dan keuntungan menjadi ekspresi pelat yang valid. Itu bagian sublingu DSL / data.