Theo bài viết này , dòng mã Lisp sau đây in "Hello world" thành đầu ra tiêu chuẩn.
(format t "hello, world")
Lisp, một ngôn ngữ đồng âm , có thể coi mã là dữ liệu theo cách này:
Bây giờ hãy tưởng tượng rằng chúng ta đã viết macro sau:
(defmacro backwards (expr) (reverse expr))
ngược là tên của macro, lấy một biểu thức (được biểu diễn dưới dạng danh sách) và đảo ngược nó. Đây là "Xin chào, thế giới" một lần nữa, lần này sử dụng macro:
(backwards ("hello, world" t format))
Khi trình biên dịch Lisp nhìn thấy dòng mã đó, nó nhìn vào nguyên tử đầu tiên trong danh sách (
backwards
) và thông báo rằng nó đặt tên cho một macro. Nó chuyển danh sách không được("hello, world" t format)
đánh giá sang macro, sắp xếp lại danh sách(format t "hello, world")
. Danh sách kết quả thay thế biểu thức macro và đó là những gì sẽ được đánh giá tại thời gian chạy. Môi trường Lisp sẽ thấy rằng nguyên tử đầu tiên của nó (format
) là một hàm và đánh giá nó, chuyển nó sang phần còn lại của các đối số.
Trong Lisp, việc đạt được nhiệm vụ này rất dễ dàng (sửa tôi nếu tôi sai) vì mã được triển khai dưới dạng danh sách ( s-biểu thức ?).
Bây giờ hãy xem đoạn trích OCaml này (không phải là ngôn ngữ đồng âm):
let print () =
let message = "Hello world" in
print_endline message
;;
Hãy tưởng tượng bạn muốn thêm đồng âm vào OCaml, sử dụng cú pháp phức tạp hơn nhiều so với Lisp. Bạn làm điều đó như thế nào? Liệu ngôn ngữ phải có một cú pháp đặc biệt dễ dàng để đạt được đồng âm?
EDIT : từ chủ đề này, tôi đã tìm ra một cách khác để đạt được tính đồng âm khác với Lisp: cách thực hiện bằng ngôn ngữ io . Nó có thể trả lời một phần câu hỏi này.
Ở đây, hãy bắt đầu với một khối đơn giản:
Io> plus := block(a, b, a + b) ==> method(a, b, a + b ) Io> plus call(2, 3) ==> 5
Được rồi, vì vậy khối hoạt động. Khối cộng thêm hai số.
Bây giờ chúng ta hãy làm một số nội tâm về người bạn nhỏ này.
Io> plus argumentNames ==> list("a", "b") Io> plus code ==> block(a, b, a +(b)) Io> plus message name ==> a Io> plus message next ==> +(b) Io> plus message next name ==> +
Nóng lạnh khuôn lạnh. Bạn không chỉ có thể nhận được tên của các thông số khối. Và không chỉ bạn có thể có được một chuỗi mã nguồn hoàn chỉnh của khối. Bạn có thể lẻn vào mã và duyệt các tin nhắn bên trong. Và tuyệt vời nhất trong tất cả: nó cực kỳ dễ dàng và tự nhiên. Đúng như nhiệm vụ của Io. Gương của Ruby không thể thấy bất cứ thứ gì trong số đó.
Nhưng, whoa whoa, hey, đừng chạm vào mặt số đó.
Io> plus message next setName("-") ==> -(b) Io> plus ==> method(a, b, a - b ) Io> plus call(2, 3) ==> -1