การทอโค้ด Byte กับ Lisp แมโคร


11

ฉันได้อ่านเกี่ยวกับห้องสมุดที่ผู้คนเขียนสำหรับภาษาอย่าง Java และ C # ซึ่งใช้ประโยชน์จากรหัสไบต์ที่ทอผ้าเพื่อทำสิ่งต่าง ๆ เช่นการตัดการเรียกใช้ฟังก์ชันการแทรกรหัสการบันทึก ฯลฯ ฉันได้อ่านมาโคร Lisp / Clojure ด้วย พยายามเข้าใจวิธีการใช้งานให้ดีขึ้น ยิ่งฉันอ่านมาโครมากเท่าไหร่ก็ยิ่งมีความสามารถในการทำงานเหมือนกับไลบรารีการทอโค้ดไบต์ โดยฟังก์ชั่นฉันหมายถึงความสามารถในการจัดการรหัสในเวลารวบรวม

ตัวอย่างของห้องสมุดที่ฉันดูอยู่จะเป็น AspectJ, PostSharp และ Cecil

มีสิ่งใดบ้างที่สามารถทำได้กับสิ่งหนึ่งและอีกอันหนึ่งไม่ใช่หรือ พวกเขาแก้ปัญหาเดียวกันได้จริงหรือฉันกำลังเปรียบเทียบแอปเปิ้ลกับส้ม?


2
การทอโค้ดไบต์เป็นวิธีการแก้ไขเมื่อคุณต้องการภาษาแบบไดนามิก แต่ติดอยู่กับภาษาที่พิมพ์แบบคงที่
kevin cline

2
@ kevincline คุณพยายามที่จะเริ่มการต่อสู้แบบเก่านี้หรือไม่?
Jonathan Henson

คำตอบ:


10

การทอโค้ดไบต์และมาโครเป็นสองสิ่งที่แตกต่างกัน

การทอโค้ด Byte เป็นวิธีหนึ่งในการสกัดกั้นการเรียกใช้ฟังก์ชันดังนั้นคุณสามารถฉีดฟังก์ชันบางอย่าง (โดยทั่วไปเกี่ยวข้องกับการตัดข้ามเช่นการบันทึก) ลงในการเรียกใช้ฟังก์ชั่นไม่ว่าจะก่อนหรือหลังฟังก์ชั่น การทอรหัสไบต์จะทำที่ระดับรหัสไบต์ซึ่งหมายความว่าจะเกิดขึ้นหลังจากการรวบรวม ฟังก์ชั่นนั้นไม่ได้รับผลกระทบ นี่เป็นหนึ่งในเทคนิคที่Aspect Oriented Programmingใช้

มาโครเป็นวิธีการขยายไวยากรณ์ของภาษา ในรูปแบบที่ง่ายที่สุดแมโครเป็นวิธีบันทึกการกดแป้นพิมพ์จากนั้นเล่นโดยใช้ปุ่มลัด มาโครภาษาทำงานคล้ายกัน คำหลักหรือทดแทนการสร้างไวยากรณ์อื่น ๆ สำหรับการขยายตัวของแมโครบางประเภท แน่นอนเกินไป เป็นตัวอย่างที่ดีของการที่เฉพาะเจาะจงแมโครเพื่อเสียงกระเพื่อมสามารถพบได้ที่นี่


+1 สำหรับการกล่าวถึงว่านี่เป็นวิธีการสำคัญในการใช้ AOP
Jonathan Henson

และการทำธุรกรรม ... ขอให้เราอย่าลืมการทำธุรกรรม
Jonathan Henson

3
มาโคร LISP ไม่เหมือน 'วิธีการบันทึกการกดแป้น'
kevin cline

1
แนวคิดพื้นฐานบางอย่างหายไปจากคำตอบ IMO นั่นอาจเป็น: AST, การสะท้อน, การเปลี่ยนแปลงของเซลล์
AndreasScheinert

2
@AndreasScheinert: OP ไม่ได้ถามเกี่ยวกับสิ่งเหล่านั้น นี่ไม่ใช่วิทยานิพนธ์ มันเป็นเพียงคำตอบสำหรับคำถามของ OP
Robert Harvey

5

แม้ว่ามันอาจจะใช้ในจุดสิ้นสุดเดียวกันมาโคร LISP นั้นค่อนข้างแตกต่างจากปลั๊กอินการทอโค้ด Java byte มาโคร LISP ขยายไวยากรณ์ LISP ที่ระดับซอร์สโค้ด LISP เนื่องจากแมโคร LISP ถูกเขียนในระดับเดียวกับรหัส LISP อื่น ๆ จึงเป็นคุณสมบัติภาษาที่ใช้กันทั่วไป

ปลั๊กอินการทอโค้ด Java byte-Java ทำงานที่ระดับ JVM ในขณะที่โปรแกรมเมอร์ Java ส่วนใหญ่อาจใช้ปลั๊กอินการทอไบต์โค้ดที่เขียนโดยผู้อื่นโปรแกรมเมอร์ Java น้อยมากที่เขียนปลั๊กอินการทอไบต์โค้ดของตนเอง

งานบางส่วนที่ทำโดยปลั๊กอินคอมไพเลอร์ Java ทำได้ง่ายมากในภาษาแบบไดนามิก การสกัดกั้นฟังก์ชั่นการโทรนั้นง่ายมาก


ฉันเข้าใจความแตกต่างทางเทคนิคระหว่างสองสิ่งนี้ ฉันพยายามดูคำถามจากมุมมองระดับสูง เครื่องมือทั้งสองสามารถจัดการรหัสเพื่อให้บรรลุเป้าหมายเดียวกันได้หรือไม่ มีปัญหาใดบ้างที่มาโครไม่สามารถแก้ไขได้ว่าการจัดการแบบ bytecode สามารถทำได้ (อย่างมีสติและประหยัดค่าใช้จ่าย)? นั่นคือสิ่งที่ฉันจะทำ
mortalapeman

@mortalapeman: การปรับเปลี่ยนที่เป็นไปได้ใน Java และ C # ผ่านการแก้ไขโค้ดไบต์สามารถทำได้โดยตรงในภาษาต่างๆเช่น Lisp, Ruby, Python, Lua, Javascript ... เป็นไปได้ที่จะทำทุกอย่างที่มาโคร LISP สามารถทำได้ผ่านไบต์ การจัดการรหัส แต่ในทางปฏิบัติที่ไม่เกิดขึ้น
วินไคลน์

4

แมโคร Lisp ทำงานในระดับซอร์สโค้ด หากคุณใส่มาโครไว้รอบ ๆ โค้ดคุณก็สามารถทำสิ่งต่างๆมากมายได้ การแยกวิเคราะห์ซอร์สโค้ดการใส่รหัสการเขียนใหม่เป็นต้น

หากคุณต้องการแก้ไขการเรียกใช้ฟังก์ชั่น Lisp มักใช้กลไกสองอย่าง:

  • สัญลักษณ์ผูกปลาย คุณสามารถแก้ไขฟังก์ชั่นที่ถูกผูกไว้กับสัญลักษณ์ ทุกฟังก์ชั่นการโทรที่ต้องผ่านสัญลักษณ์จากนั้นใช้ฟังก์ชั่นใหม่

  • การใช้งานเสียงกระเพื่อมบางครั้งมีคุณสมบัติที่เรียกว่า 'คำแนะนำ' วิธีนี้ทำให้สามารถเรียกใช้งานรหัสก่อนหลังหรือรอบ ๆ การโทรได้ ยกตัวอย่างเช่นใน LispWorks: แนะนำ

ดังนั้นคุณสามารถสกัดกั้นการโทรโดยไม่มีการจัดการรหัสระดับต่ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.