Mã byte dệt vs macro Lisp


11

Tôi đã đọc về các thư viện mà mọi người đã viết cho các ngôn ngữ như Java và C # sử dụng dệt mã byte để thực hiện các công việc như chặn cuộc gọi hàm, chèn mã đăng nhập, v.v. Tôi cũng đã đọc các macro Lisp / Clojure trong một cố gắng để hiểu rõ hơn về cách sử dụng chúng. Càng đọc nhiều về macro, dường như chúng càng cung cấp loại chức năng tương tự như các thư viện dệt mã byte. Theo chức năng, tôi có nghĩa là khả năng thao tác mã tại thời gian biên dịch.

Ví dụ về các thư viện tôi đã xem xét sẽ là AspectJ, PostSharp và Cecil.

Có bất cứ điều gì có thể được thực hiện với một và không phải là khác? Họ thực sự giải quyết các vấn đề tương tự hay tôi đang so sánh táo và cam?


2
dệt mã byte là một công việc xung quanh khi bạn cần một ngôn ngữ động nhưng bị mắc kẹt với một ngôn ngữ được gõ tĩnh
kevin cline

2
@kevincline bạn đang nghiêm túc cố gắng để bắt đầu cuộc chiến cũ này?
Jonathan Henson

Câu trả lời:


10

Dệt mã byte và macro là hai thứ khác nhau.

Dệt mã byte là một cách để chặn các cuộc gọi chức năng, do đó bạn có thể đưa một số loại chức năng (thường là mối quan tâm xuyên suốt như ghi nhật ký) vào một cuộc gọi chức năng, trước hoặc sau khi chức năng được thực thi. Việc dệt mã byte được thực hiện ở cấp mã byte, có nghĩa là nó xảy ra sau khi biên dịch. Các chức năng chính nó không bị ảnh hưởng. Đây là một trong những kỹ thuật mà Lập trình hướng theo khía cạnh sử dụng.

Macro là một cách để mở rộng cú pháp của ngôn ngữ. Ở dạng đơn giản nhất, macro chỉ đơn giản là một cách để ghi lại các lần nhấn phím, sau đó phát lại chúng bằng phím nóng. Macro ngôn ngữ hoạt động theo cách tương tự; một từ khóa hoặc cú pháp khác xây dựng thay thế cho một số loại mở rộng macro. Điều này là quá đơn giản, tất nhiên; một ví dụ tốt hơn về một macro cụ thể cho Lisp có thể được tìm thấy ở đây .


+1 để đề cập rằng đây là một cách chính để thực hiện AOP.
Jonathan Henson

Và giao dịch ... chúng ta đừng quên giao dịch.
Jonathan Henson

3
Các macro LISP không giống như "một cách để ghi lại các lần nhấn phím".
kevin cline

1
Vâng, một số khái niệm cơ bản bị thiếu trong câu trả lời IMO, đó có thể là: AST, phản xạ, Metacircularity.
AndreasScheinert

2
@AndreasScheinert: OP đã không hỏi về bất kỳ điều gì trong số đó. Đây không phải là một luận án; nó chỉ là một câu trả lời cho câu hỏi của OP.
Robert Harvey

5

Mặc dù chúng có thể được sử dụng cho cùng một kết thúc, các macro LISP hoàn toàn khác với các plugin dệt mã byte của Java. Các macro LISP mở rộng cú pháp LISP ở cấp mã nguồn LISP. Vì các macro LISP được viết ở cùng cấp độ với mã LISP khác, chúng là một tính năng ngôn ngữ thường được sử dụng.

Các plugin dệt mã byte Java hoạt động ở mức JVM. Trong khi nhiều lập trình viên Java có thể sử dụng các trình cắm dệt mã byte do người khác viết, thì rất ít lập trình viên Java viết các trình cắm dệt mã byte của riêng họ.

Một số công việc được thực hiện bởi các trình biên dịch Java được thực hiện rất dễ dàng bằng các ngôn ngữ động. Chức năng chặn cuộc gọi đặc biệt đơn giản.


Tôi hiểu sự khác biệt kỹ thuật giữa hai. Tôi đã cố gắng nhìn vào câu hỏi từ quan điểm cấp cao. Cả hai công cụ có thể thao tác mã để đạt được cùng một mục tiêu không? Có bất kỳ vấn đề nào mà các macro không thể giải quyết được rằng thao tác mã byte có thể (một cách hiệu quả và tiết kiệm chi phí) không? Đó là nhiều hơn những gì tôi đã đi.
chết

@mortalapeman: các thao tác có thể có trong Java và C # thông qua sửa đổi mã byte đều có thể được thực hiện trực tiếp bằng các ngôn ngữ như Lisp, Ruby, Python, Lua, Javascript ... Có thể thực hiện mọi thứ mà macro LISP có thể thực hiện thông qua byte Thao tác mã-nhưng, trong thực tế điều đó không xảy ra.
kevin cline

4

Các macro Lisp đang hoạt động ở cấp mã nguồn. Nếu bạn bọc một số macro xung quanh một đoạn mã, thì bạn có thể làm rất nhiều thứ. Bao gồm phân tích mã nguồn, chèn mã, viết lại mã, v.v.

Nếu bạn muốn sửa đổi các cuộc gọi chức năng, Lisp thường sử dụng hai cơ chế:

  • biểu tượng ràng buộc muộn. Bạn có thể sửa đổi chức năng ràng buộc với một biểu tượng. Mỗi hàm gọi đi qua một ký hiệu, sau đó sử dụng hàm mới.

  • Việc triển khai Lisp đôi khi cung cấp một tính năng gọi là 'lời khuyên'. Điều này cho phép thực thi mã trước, sau hoặc xung quanh các cuộc gọi. Ví dụ trong LispWorks: Lời khuyên .

Do đó, bạn có thể chặn các cuộc gọi mà không cần thao tác mã cấp thấp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.