Sự khác nhau giữa `eval` và `apply` là gì?

Tao không thích kiểu suy nghĩ này. Đây là dữ liệu:

(+ 4 5)

bởi vì cái này là dữ liệu:

(1 2 3)

cái này là dữ liệu:

(X Y Z)

Eval đơn giản chỉ là một hàm tuân theo một số quy tắc được đưa ra từ một số dữ liệu. Chỉ vậy thôi.

Một trong những quy tắc đó có thể tạo ra nhiều hàm hơn. Quy tắc đó được gọi là “lambda”.

Một quy tắc khác trả về dữ liệu. Quy tắc đó được gọi là “quote”.

Một quy tắc khác nữa áp dụng các đối số cho một hàm. Quy tắc đó được gọi là “apply”.

Kiểu suy nghĩ này cho chúng ta một khuôn khổ tuyệt vời để suy nghĩ về lisp, và điều đó cho chúng ta một công cụ để tìm ra (a) tại sao eval lại “nguy hiểm” trong các ngôn ngữ khác và (b) những gì cần thiết để làm cho eval “an toàn” như trong lisp.

Kiểu suy nghĩ này cũng làm cho chế độ SICP rõ ràng hơn: Ở chỗ chúng ta nghĩ mình đang lập trình, chúng ta chỉ đang mô tả dữ liệu, và chính eval là người tuân theo những quy tắc đó;

Nếu chúng ta nhìn vào việc triển khai “eval” (như chúng ta làm trong SICP), chúng ta có thể thấy rằng quy tắc “apply” gọi một hàm có tên là “apply” – nhưng ai đang đánh giá nó? Thật khó để thấy trong định nghĩa “vòng tròn” này làm thế nào eval có thể được triển khai dựa trên apply, và apply có thể được triển khai dựa trên eval, nhưng điều này chỉ là bởi vì chúng ta nghĩ mình đang lập trình trong lisp của mình! Khi chúng ta suy nghĩ về nó một cách chính xác, chúng ta sẽ tưởng tượng một cái thang của các lisp, với mỗi eval triển khai apply của lisp cấp thấp hơn của nó.

Việc gây nhầm lẫn về telnet và passwd là không có trách nhiệm. Nó không làm cho SICP rõ ràng hơn, và nó thậm chí không bắt đầu giải thích câu hỏi về sự khác biệt giữa eval và apply là gì, và quan trọng hơn, nó thậm chí không phải là một cách hữu ích để giúp ai đó hiểu các khái niệm lisp mà sau này họ có thể sửa lại bằng tư duy lisp tốt.