2015-09-02 21 views
5

tôi thấy rằng chương trình để kiểm tra xem Phạm vi là từ vựng hoặc động là người đưa ra dưới đây (nguồn: http://inst.eecs.berkeley.edu/~cs61a/su10/resources/sp11-Jordy/scope/)Chương trình để kiểm tra xem Phạm vi là từ vựng hoặc động

(define test 
    (let ((scope 'lexical)) 
    (lambda() scope))) 

(let ((scope 'dynamic)) 
    (test)) 

Nhưng làm thế nào có thể làm việc này? Điều này sẽ luôn luôn in 'từ vựng (không phụ thuộc vào phạm vi là từ vựng hay động) phải không? vì trong phạm vi địa phương của nội dung của 'let' đầu tiên, phạm vi luôn được định nghĩa là 'lexical .. Vui lòng sửa tôi nếu i am sai

Trả lời

6

Đề án sử dụng phạm vi từ vựng, do đó, mã đó luôn trả về lexical. Tuy nhiên, trong hệ thống Lisp sử dụng phạm vi động, scope thực sự sẽ là dynamic bên trong biểu thức (let ((scope 'dynamic)) ...) đó….

Để hiểu điều đó, bạn phải hiểu cách triển khai phạm vi động. Hãy suy nghĩ của từng biến như có một chồng các giá trị. Vì vậy, khi biểu thức lambda đang được đánh giá, giá trị lexical đã được đẩy tới ngăn xếp giá trị của scope (qua số let). Khi khối let bị thoát, giá trị sẽ bị tắt. Sau đó, khối let thứ hai đẩy giá trị của ngăn xếp giá trị dynamic đến scope, đó là chức năng mà sau đó bạn thấy.

Tôi đánh giá cao the explanation from the Emacs Lisp manual về cách liên kết động hoạt động theo một chồng. Nó đã giúp tôi thực sự hiểu khái niệm theo các điều kiện cụ thể.

+0

Tôi hiểu các chương trình trong liên kết và khái niệm ngăn xếp được giải thích ở đây. Cảm ơn bạn đã thông tin. Nhưng khi hàm test được gọi từ lệnh 'let' thứ hai, mã bên trong khối define được thực thi và khối let cho bên trong hàm test sẽ lại đẩy giá trị 'lexical đến stack trước khi khối lambda được thực thi, phải không ?. .. hoặc vấn đề trong sự hiểu biết của tôi về việc thực thi là gì? –

+2

@SubinP 'define' không được thực thi khi bạn gọi hàm, hàm đã được định nghĩa là' (lambda() scope) '. – molbdnilo

+0

Cảm ơn, giờ đã rõ ràng –

6

Giá trị của test không phải là

(let ((scope 'lexical)) 
    (lambda() scope)) 

nó chỉ là

(lambda() scope) 

Khi bạn gọi nó, (test), cơ quan chức năng được đánh giá, và nó bao gồm duy nhất của

scope 

Với phạm vi từ vựng, đây sẽ là giá trị trong liên kết được thực hiện ect khi định nghĩa được đánh giá, tức là liên kết với nhau let.

Với phạm vi động, ràng buộc scope không được tìm kiếm cho đến khi hàm được gọi.
Tại thời điểm đó, liên kết với 'lexical đã biến mất lâu - nó chỉ tồn tại trong khi định nghĩa test.

Khi bạn

(let ((scope 'dynamic)) 
    (test)) 

một ràng buộc mới được giới thiệu trong môi trường, và đây là ràng buộc được tìm thấy khi nhìn lên scope.

Các chức năng tương tự

(define test 
    (lambda() 
     (let ((scope 'whatever)) 
      scope))) 

sẽ làm việc theo cách bạn đề nghị - luôn luôn trở về 'whatever - như các ràng buộc để 'whatever có hiệu lực trong việc đánh giá scope thậm chí trong một khung cảnh động.

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