Có ai có thể giải thích sự khác biệt đơn giản không? Tôi không nghĩ rằng tôi hiểu khái niệm từ sách giáo khoa/trang web tôi đã tham khảo ý kiến.Bối rối bởi sự khác biệt giữa let và let * trong Đề án
Trả lời
Nếu bạn sử dụng let
, bạn không thể tham chiếu các liên kết được xác định trước đó trong cùng một biểu thức let
. Ví dụ, điều này sẽ không làm việc:
(let ((x 10)
(y (+ x 6))) ; error! unbound identifier in module in: x
y)
Nhưng nếu bạn sử dụng let*
, nó có thể tham khảo các ràng buộc trước đó trong biểu thức let*
cùng:
(let* ((x 10)
(y (+ x 6))) ; works fine
y)
=> 16
Đó là tất cả here trong tài liệu.
Tôi không nhìn thấy nó rõ ràng trong tài liệu (nơi liên kết của bạn điểm, phiên bản hiện tại 5.3.6), vì vậy tôi đã nhầm lẫn quá. Tài liệu cho 'let' nói rằng" Dạng đầu tiên đánh giá 'val-exprs' từ trái sang phải, ...", vì vậy không rõ là chúng được đánh giá song song. – Alexey
@Alexey nó không đánh giá chúng song song. Như các tài liệu nói, * "Hình thức đầu tiên đánh giá' val-exprs' từ trái sang phải, tạo một vị trí mới cho mỗi 'id', và đặt các giá trị vào các vị trí" * - có nghĩa là, trước tiên chúng được đánh giá và các giá trị kết quả được thu thập, và chỉ *** sau đó *** các vị trí mới được tạo cho mỗi '' id' * và các giá trị được đặt vào vị trí của nó. Bạn vẫn có thể thấy tuần tự nếu một trong các 'val-exprs' * biến đổi một bộ nhớ (tức là dữ liệu, như danh sách hoặc cấu trúc) được truy cập bởi bộ nhớ tiếp theo. –
Let
là song song, (loại; xem dưới đây)let*
là tuần tự. Let
dịch là
((lambda(a b c) ... body ...)
a-value
b-value
c-value)
nhưng let*
như
((lambda(a)
((lambda(b)
((lambda(c) ... body ...)
c-value))
b-value))
a-value)
và do đó tạo ra khối phạm vi lồng nhau nơi b-value
biểu có thể tham khảo a
, và c-value
biểu có thể tham khảo cả b
và a
. a-value
thuộc phạm vi bên ngoài. Đây cũng là tương đương với
(let ((a a-value))
(let ((b b-value))
(let ((c c-value))
... body ...)))
cũng letrec
Có, cho phép bindings đệ quy, nơi tất cả các biến và các biểu thức thuộc về một phạm vi chia sẻ và có thể tham khảo lẫn nhau (với một số hãy cẩn thận liên quan đến khởi tạo). Nó tương đương với một trong hai để
(let ((a *undefined*) (b *undefined*) (c *undefined*))
(set! a a-value)
(set! b b-value)
(set! c c-value)
... body ...)
(in Racket, cũng có sẵn như letrec*
trong Đề án, kể từ R6RS), hoặc để
(let ((a *undefined*) (b *undefined*) (c *undefined*))
(let ((_x_ a-value) (_y_ b-value) (_z_ c-value)) ; unique identifiers
(set! a _x_)
(set! b _y_)
(set! c _z_)
... body ...))
(in Scheme).
cập nhật: let
không thực sự đánh giá biểu thức giá trị song song, chỉ là tất cả đều được đánh giá trong cùng một môi trường ban đầu nơi biểu mẫu let
xuất hiện. Đây cũng là rõ ràng từ bản dịch dựa trên lambda
: thứ nhất các biểu thức giá trị được đánh giá mỗi trong cùng một môi trường, ngoài, và các giá trị kết quả được thu thập, và chỉ sau đó địa điểm mới được tạo ra cho mỗi id và các giá trị được đặt vào vị trí của nó. Chúng tôi vẫn có thể thấy tuần tự nếu một trong các biểu thức giá trị làm thay đổi bộ nhớ (tức là dữ liệu, như danh sách hoặc cấu trúc) được truy cập bởi một lần tiếp theo.
bản sao có thể có của [Đề án gây nhầm lẫn cho Let và Let \ *] (http: // stackoverflow.com/questions/8036840/scheme-confusing-of-let-and-let) –
@DavidPfeffer - Dường như không phải là một bản dupe. Người ta đang hỏi về một sự tương tác rất cụ thể của 'let' và' let * 's lồng nhau, trong khi cái này đang yêu cầu một cái nhìn tổng quan chung. – Inaimathi
chỉ đơn giản là nhầm lẫn giải thích của con người về máy exectution: o – Nishant