Saya telah membaca tentang perpustakaan yang ditulis orang untuk bahasa seperti Java dan C # yang menggunakan tenun kode byte untuk melakukan hal-hal seperti panggilan fungsi intersep, memasukkan kode logging, dll. Saya juga membaca di Lisp / Clojure macro di sebuah mencoba untuk lebih memahami bagaimana memanfaatkannya. Semakin banyak saya membaca tentang makro, semakin banyak sepertinya mereka menyediakan fungsionalitas yang sama dengan perpustakaan byte code tenun. Secara fungsional, maksud saya kemampuan untuk memanipulasi kode pada waktu kompilasi.
Contoh perpustakaan yang telah saya lihat adalah AspectJ, PostSharp, dan Cecil.
Adakah yang bisa dilakukan dengan yang satu dan bukan yang lain? Apakah mereka benar-benar memecahkan masalah yang sama atau apakah saya membandingkan apel dan jeruk?
sumber
Jawaban:
Tenun kode byte dan makro adalah dua hal yang berbeda.
Tenun kode byte adalah cara untuk mencegat panggilan fungsi, sehingga Anda dapat menyuntikkan semacam fungsionalitas (umumnya masalah lintas sektoral seperti pencatatan) ke dalam panggilan fungsi, baik sebelum atau setelah fungsi dijalankan. Tenun kode byte dilakukan pada level kode byte, yang berarti terjadi setelah kompilasi. Fungsi itu sendiri tidak terpengaruh. Ini adalah salah satu teknik yang digunakan Pemrograman Berorientasi Aspek .
Makro adalah cara untuk memperpanjang sintaks suatu bahasa. Dalam bentuknya yang paling sederhana, makro hanyalah cara untuk merekam penekanan tombol, dan kemudian memutarnya menggunakan hot key. Makro bahasa bekerja dengan cara yang sama; kata kunci atau sintaks konstruksi pengganti untuk beberapa jenis ekspansi makro. Ini terlalu disederhanakan, tentu saja; contoh makro khusus untuk Lisp yang lebih baik dapat ditemukan di sini .
sumber
Meskipun mereka dapat digunakan untuk tujuan yang sama, makro LISP sangat berbeda dari plugin tenun kode byte Java. Makro LISP memperluas sintaks LISP di tingkat kode sumber LISP. Karena makro LISP ditulis pada tingkat yang sama dengan kode LISP lainnya, mereka adalah fitur bahasa yang umum digunakan.
Plugin tenun kode byte Java beroperasi pada level JVM. Sementara banyak programmer Java dapat menggunakan plugin tenun byte-code yang ditulis oleh orang lain, sangat sedikit programmer Java yang menulis plugin tenun byte-code mereka sendiri.
Beberapa pekerjaan yang dilakukan oleh plugin kompiler Java sangat mudah dilakukan dalam bahasa dinamis. Intersepsi panggilan fungsi sangat sederhana.
sumber
Macro Lisp beroperasi di tingkat kode sumber. Jika Anda membungkus makro di sekitar sepotong kode, maka Anda dapat melakukan banyak hal. Termasuk penguraian kode sumber, memasukkan kode, menulis ulang kode, dll.
Jika Anda ingin memodifikasi panggilan fungsi, Lisp biasanya menggunakan dua mekanisme:
simbol pengikat yang terlambat. Anda dapat memodifikasi fungsi yang terikat pada simbol. Setiap pemanggilan fungsi yang melewati simbol, lalu menggunakan fungsi baru.
Implementasi Lisp terkadang menyediakan fitur yang disebut 'saran'. Ini memungkinkan untuk mengeksekusi kode sebelum, setelah atau sekitar panggilan. Misalnya di LispWorks: Saran .
Dengan demikian Anda dapat mencegat panggilan tanpa manipulasi kode tingkat rendah.
sumber