2009-07-23 26 views
49

Tôi mới bắt đầu làm việc thông qua SICP (một mình, đây không phải là một lớp học), và tôi đã đấu tranh với Bài tập 1.6 trong một vài ngày và tôi dường như không thể hình dung ra . Đây là một trong những nơi Alyssa tái định nghĩa if về cond, như vậy:Giải thích cho Bài tập 1.6 trong SICP là gì?

(define (new-if predicate then-clause else-clause) 
    (cond (predicate then-clause) 
      (else else-clause)) 

Cô kiểm tra nó thành công trên một số trường hợp đơn giản, và sau đó sử dụng nó để viết lại chương trình căn bậc hai (mà làm việc chỉ tốt với if):

(define (sqrt-iter guess x) 
    (new-if (good-enough? guess x) 
      guess 
      (sqrt-iter (improve guess x) 
         x))) 

câu hỏi đặt ra sau đó hỏi: "Điều gì sẽ xảy ra khi Alyssa cố gắng sử dụng này để tính căn bậc hai Giải thích?". [Nếu cần thiết, tôi rất vui để tạo lại các thủ tục khác (good-enough?, improve, vv), chỉ cho tôi biết.]

Bây giờ, tôi biết những gì sẽ xảy ra: nó không bao giờ trả về một giá trị, có nghĩa là chương trình đệ quy vô hạn. Tôi chỉ không thể giải thích tại sao điều này xảy ra. Bất kỳ sự khác biệt tinh tế nào tồn tại giữa các số ifnew-if đều làm tôi khó chịu. Bất kỳ và tất cả giúp đỡ nhiều đánh giá cao.

+1

Dạng động từ "đệ quy" là "để recurse", do đó, nó "recurses". –

+0

tiêu đề câu hỏi của bạn sai: bạn đang tham khảo Bài tập 1.6, không phải 1.4. – systemovich

+1

@Geoffrey Van Wyk Bạn nói đúng. Vào thời điểm tôi viết câu hỏi, tôi đã làm việc thông qua bản sao cũ của Ấn bản SICP thứ nhất, trong đó vấn đề này xuất hiện dưới dạng Bài tập 1.4. Trong ấn bản thứ 2, đó là Bài tập 1.6. Tôi sẽ thực hiện thay đổi. –

Trả lời

62

new-if là một hàm. Khi một hàm được gọi, điều đầu tiên mà Lược đồ làm với danh sách đối số là gì? Nó đánh giá tất cả các đối số.

20

Trước hết, bạn phải understand the difference giữa đánh giá đơn đặt hàng và thứ tự bình thường. Lisp sử dụng để applicative, nhưng biểu thức điều kiện được đánh giá không giống như các chức năng bình thường (sicp chapter 1.1.6):

(if <predicate> <consequent> <alternative>) 

Để đánh giá một nếu biểu hiện, người phiên dịch bắt đầu bằng việc đánh giá <predicate> phần của biểu thức. Nếu số <predicate> đánh giá thành giá trị thực, thì thông dịch viên sẽ đánh giá <consequent> và trả về giá trị của nó. Nếu không, nó sẽ đánh giá <alternative> và trả về giá trị của nó.

28

new-if là một thủ tục, và Đề án sử dụng đánh giá applicative đặt hàng (1.1.5), do đó ngay cả trước khi new-if được thực hiện, nó phải đánh giá tất cả các đối số đầu tiên, đó là guess(sqrt-iter (improve guess x) x). Bạn có thể thấy rằng đối số thứ hai là đệ quy, gọi thủ tục new-if mới, đây là cách vòng lặp vô hạn xảy ra.

Thông thường if không cần đánh giá đối số của nó trước, chỉ cần đi dọc đường, đây là sự khác biệt giữa ifnew-if. :)

+0

Thủ tục 'new-if' có ba đối số:' predicate', 'then-clause' và' else-clause'. Vì vậy, khi 'new-if' được gọi,' (tốt-đủ? Đoán x) ',' đoán' và '(sqrt-iter (cải thiện đoán x))' được đánh giá. Có đúng không ? Điều này không thay đổi kết quả vì chỉ đánh giá 'sqrt-iter' gây ra rắc rối. Nhưng bạn quên mất một đối số ... –

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