Trong sơ đồ R5RS đơn giản, không có hệ thống mô-đun nào - chỉ có sự to lớn. thermore, tâm lý là tất cả mọi thứ có thể được sửa đổi, vì vậy bạn có thể "tùy chỉnh" ngôn ngữ bất kỳ cách nào bạn muốn. Nhưng không có một hệ thống mô-đun, điều này không hoạt động tốt. Ví dụ, tôi viết
(define (sub1 x) (- x 1))
trong một thư viện mà bạn nạp - và bây giờ bạn có thể xác định lại -
:
(define - +) ; either this
(set! - +) ; or this
và bây giờ bạn vô tình đã phá vỡ thư viện của tôi mà dựa vào sub1
decrementing đầu vào của nó bởi một và kết quả là cửa sổ của bạn sẽ tăng lên khi bạn kéo chúng xuống hoặc bất kỳ thứ gì.
Cách duy nhất xung quanh này, được sử dụng bởi một số thư viện, là để "lấy" định nghĩa liên quan của hàm subtraction, trước khi ai đó có thể sửa đổi nó:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))
Bây giờ mọi thứ sẽ làm việc "nhiều mỹ ", vì bạn không thể sửa đổi ý nghĩa của hàm sub1
của tôi bằng cách thay đổi -
. (Ngoại trừ ... nếu bạn sửa đổi nó trước khi bạn tải thư viện của mình ...)
Dù sao, do kết quả này (và nếu bạn biết rằng -
là thư gốc khi thư viện được tải), một số trình biên dịch sẽ phát hiện điều này và thấy rằng cuộc gọi -
luôn là hàm trừ thực tế và do đó chúng sẽ gọi nội tuyến tới nó (và nội tuyến gọi -
cuối cùng có thể dẫn đến mã lắp ráp để trừ hai số, vì vậy đây là tăng tốc độ lớn). Nhưng như tôi đã nói trong bình luận ở trên, điều này trùng hợp hơn với lý do thực sự ở trên.
Cuối cùng, R6RS (và một số triển khai chương trình trước đó) đã sửa lỗi này và thêm hệ thống thư viện, do đó không sử dụng được mẹo này: mã sub1
là an toàn miễn là mã khác trong thư viện của nó không được xác định lại -
một cách nào đó, và trình biên dịch có thể tối ưu hóa một cách an toàn mã dựa trên điều này. Không cần thủ thuật thông minh.
cảm ơn bạn đã phản hồi kỹ lưỡng! – redwoolf