2010-09-10 37 views
7

Tôi nghĩ rằng tôi hiểu tại sao có nguy cơ cho phép đóng cửa bằng ngôn ngữ sử dụng phạm vi động. Đó là, có vẻ như bạn sẽ có thể đóng biến OK, nhưng khi cố gắng đọc nó, bạn sẽ chỉ nhận được giá trị ở trên cùng của ngăn xếp toàn cầu. Điều này có thể nguy hiểm nếu các chức năng khác sử dụng cùng một tên trong thời gian tạm thời.Đóng và phạm vi động?

Tôi đã bỏ lỡ một số sự tinh tế khác?

Trả lời

6

Vâng, đó là vấn đề cơ bản. Thuật ngữ "đóng cửa" là viết tắt của "đóng cửa từ vựng", mặc dù, mà by definition captures its lexical scope. Tôi muốn gọi những thứ bằng ngôn ngữ động có phạm vi khác, chẳng hạn như LAMBDA. Lambdas là hoàn toàn an toàn trong một ngôn ngữ động phạm vi miễn là bạn không cố gắng trả lại chúng.

(Để có một thử nghiệm suy nghĩ thú vị, hãy so sánh vấn đề trả về lambda phạm vi động trong Emacs Lisp về vấn đề trả về tham chiếu đến biến được phân bổ theo stack trong C và cả hai đều không thể trong Đề án.)

Một thời gian dài trước đây, trở lại khi ngôn ngữ có phạm vi động ít hơn nhiều so với hiện nay, điều này được gọi là funargs problem. Vấn đề bạn đề cập đến là vấn đề funargs hướng lên.

+3

Tôi sẽ không chỉnh sửa câu trả lời nhưng: "Thông thường" là sai - đóng luôn luôn "đóng cửa từ vựng", được đặt tên theo cách này vì chúng đóng biểu thức môi trường từ vựng. Đối với lambdas được an toàn - không có khả năng sử dụng lambdas vì các bao đóng sẽ làm giảm giá trị của chúng, nhưng ngay cả khi không có điều đó, phạm vi động vốn không tốt cho sức khỏe của chương trình vì bạn không thể chắc chắn về ý nghĩa của bất kỳ ràng buộc nào. –

+0

Cảm ơn bạn đã liên kết funargs. Tôi chưa bao giờ biết điều này trước đây. –

+0

@Eli Barzilay: Bạn nói đúng, tôi đã quá mơ hồ. Tôi sẽ loại bỏ 'thường'. Đối với sức khỏe chương trình nói chung, tôi hoàn toàn đồng ý, nhưng câu hỏi không phải là chung chung. Như tôi đã nói, lambdas có phạm vi động về an toàn như những con trỏ không hạn chế ... –

7

Tôi nhận ra mình đã trễ năm trả lời câu hỏi này, nhưng tôi đã xem qua câu hỏi này trong khi thực hiện tìm kiếm trên web và tôi muốn sửa một số thông tin sai lệch được đăng ở đây.

"Đóng cửa" chỉ có nghĩa là đối tượng có thể gọi chứa cả mã và môi trường cung cấp các ràng buộc cho các biến miễn phí trong mã đó. Môi trường đó thường là một môi trường từ vựng, nhưng không có lý do kỹ thuật nào tại sao nó không thể là một môi trường năng động.

Bí quyết là đóng mã trên môi trường chứ không phải các giá trị cụ thể. Đây là những gì Lisp 1.5 đã làm, và cũng là những gì MACLisp đã làm cho "funargs xuống."

Bạn có thể xem như thế nào Lisp 1.5 đã làm điều này bằng cách đọc 1,5 thủ Lisp tại http://www.softwarepreservation.org/projects/LISP/book

Đặc biệt chú ý tại Phụ lục B để eval xử lý CHỨC NĂNG thế nào và làm thế nào áp dụng xử lý FUNARG.

Bạn có thể nhận được hương vị cơ bản của lập trình sử dụng đóng cửa động từ http://c2.com/cgi/wiki?DynamicClosure

Bạn có thể nhận được một trong phần giới thiệu sâu vào vấn đề thực hiện từ ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf

Modern động scoped ngôn ngữ thường sử dụng cạn ràng buộc, nơi hiện tại giá trị của mỗi biến được lưu giữ ở một vị trí toàn cục và các cuộc gọi hàm sẽ lưu các giá trị cũ lên trên ngăn xếp. Một cách để triển khai các bao đóng động với ràng buộc nông được mô tả tại http://www.pipeline.com/~hbaker1/ShallowBinding.html

+0

Tôi nhận ra rằng tôi có thể trễ năm hỏi về điều này: P, nhưng bạn có thể giải thích những gì là 'make-adder',' addx', và 'do-test' tạo [link] này (http: //wiki.c2.com/?DynamicClosure) bạn đã tham chiếu? Kể từ hướng dẫn sử dụng Lisp 1.5, chúng không đóng cửa chức năng mặc dù được định nghĩa với 'lambda'. Chúng dường như giống macro hơn và được thay thế bằng các biểu thức đơn thuần (nghĩa là không có môi trường liên quan). – wlnirvana

+0

Chúng chỉ là các chức năng bình thường, có phạm vi động. Khi được gọi, họ có quyền truy cập vào các biến trong phạm vi động của họ. Đóng cửa/funarg duy nhất trong chương trình này là chương trình được tạo bởi FUNCTION. – Glomek

+0

Được rồi, có lẽ đây chỉ là vấn đề danh pháp, nhưng tôi thích nói rằng không có thứ gọi là "đóng cửa động" (cá nhân tôi nghĩ là khó hiểu hơn là làm rõ). Tài liệu tham khảo AIM-199.pdf thực sự cung cấp cho nguồn gốc của từ đóng cửa, cho thấy rằng nó lần đầu tiên được sử dụng chỉ cho các biểu thức lambda "đóng". Các hàm scoped động, có các biến tự do thoát ra môi trường thời gian chạy hiện tại, không được đóng theo nghĩa này, do đó được gọi là "biểu thức lambda mở" trong bài báo đó. – wlnirvana

Các vấn đề liên quan