Sự khác biệt giữa đánh giá đơn hàng bình thường và đơn đặt hàng


9

Ngôn ngữ tôi đang học là Scheme và tôi đang thực hiện một bài tập mang lại điều này:

(define (p) (p) )

(define (test x y) (if (= x 0)
                               0
                               y))

Sau đó, câu hỏi yêu cầu đánh giá biểu thức: (kiểm tra 0 (p)) và nhận xét về hành vi sẽ được quan sát theo đánh giá đơn hàng và đơn đặt hàng thông thường.

Đây là những suy nghĩ của tôi:

Theo thứ tự thông thường, chương trình sẽ đánh giá các biểu hiện phụ trước khi tiến hành:

Do đó ( test 0 (p) )trở thành:

(test 0 p)
( if (= x 0) 0 p))

Trả lại sản lượng 0

Sự khác biệt duy nhất trong thứ tự áp dụng là chương trình sẽ chạy như sau:

( test 0 (p) ) trở thành:

(test 0 (p))
( if (= x 0) 0 (p)))

Trả lại sản lượng 0

Do đó, (p)sẽ không bao giờ được đánh giá vì nó sẽ không cần thiết.

Điều này có đúng không? Xin vui lòng cho tôi biết vì tôi gần như không có kinh nghiệm lập trình.


1
Tôi cảm thấy câu hỏi đủ chung chung, ngoài chính ngôn ngữ Scheme, để biện minh cho việc điều trị ở đây.
babou

Câu trả lời:


19

Bạn đã làm nghiên cứu gì để trả lời câu hỏi đó? Tôi chỉ cắm nó như ở Google và nhận được câu trả lời thứ hai (câu đầu tiên có thể tốt như vậy, tôi không kiểm tra) một tham chiếu đến một phần của một cuốn kinh thánh về chủ đề của bạn: Cấu trúc của Hal Selson, Jerry Sussman và Julie Sussman và Giải thích các chương trình máy tính (MIT Press, 1984; ISBN 0-262-01077-1), còn gọi là sách hướng dẫn. Tham chiếu đến phần " Đơn hàng thông thường và Đơn hàng áp dụng ".

Nó nói:

Lược đồ là một ngôn ngữ theo thứ tự ứng dụng, cụ thể là, tất cả các đối số cho các thủ tục Đề án được đánh giá khi thủ tục được áp dụng. Ngược lại, các ngôn ngữ theo thứ tự thông thường trì hoãn việc đánh giá các đối số thủ tục cho đến khi cần các giá trị đối số thực tế.

và thêm rằng sau này được gọi là đánh giá lười biếng .

Vì vậy, bạn có định nghĩa của bạn sai, và lấy cái này cho cái kia:

  • thứ tự áp dụng đánh giá các biểu hiện phụ khi, tức là ngay trước đó, thủ tục được áp dụng.

  • thứ tự bình thường vượt qua các biểu hiện con như hiện tại mà không cần đánh giá và chỉ tiến hành đánh giá khi tham số chính thức tương ứng thực sự được đánh giá. (có một sự thay đổi hơn nữa liên quan đến vấn đề môi trường ... nhưng chúng ta nên quên điều đó vào thời điểm này).

Hơn nữa, bạn không hiểu đúng về cơ chế cuộc gọi bao gồm hai điều:

  • cơ chế truyền tham số, bao gồm xử lý đúng các đối số thực tế cho cuộc gọi, tùy thuộc vào quy tắc đánh giá;

  • phần "thay thế" của lệnh gọi hàm theo phần thân của hàm (không có tiêu đề).

Trong trường hợp thẩm định trật tự applicative của ( test 0 (p) ), bạn có nghĩa vụ phải đánh giá subxpressions số đầu tiên. Đây là 0(p).

  • đánh giá một giá trị theo nghĩa đen như 0mang lại giá trị đó.

  • tuy nhiên, đối số thứ hai là một cuộc gọi thủ tục đến một thủ tục không tham số được gọi p. Nó không có tham số, do đó chúng tôi không phải lo lắng về thứ tự đánh giá. Sau đó, để theo đuổi đánh giá, chúng ta phải thay thế cuộc gọi bằng phần thân của thủ tục theo danh sách các đối số và sau đó đánh giá phần thân đó. Phần thân của thủ tục p, như được định nghĩa bởi tuyên bố (define (p) (p) ), là (p), do đó chúng ta còn lại với việc đánh giá những gì chúng ta chỉ đang cố gắng đánh giá. Theo thứ tự, quá trình đánh giá được bắt trong một vòng lặp, và sẽ không chấm dứt.

... Và bạn không bao giờ thực sự kết thúc cuộc gọi đến hàm test, vì việc đánh giá các đối số của nó không chấm dứt. Chương trình của bạn không chấm dứt.

Nguy cơ không chấm dứt này, ngay cả khi lập luận có tội sẽ không bao giờ được sử dụng trong cuộc gọi, là một trong những lý do để sử dụng thay vì đánh giá đơn hàng bình thường, có thể khó thực hiện hơn một chút, nhưng có thể có các thuộc tính chấm dứt tốt hơn.

Theo đánh giá thứ tự thông thường , bạn không chạm vào biểu thức con đối số. Những gì bạn làm là thay thế cuộc gọi ( test 0 (p) )bằng phần thân của hàm test, nghĩa là (if (= x 0) 0 y)trong đó tên của các đối số (chính thức) xyđược thay thế bằng các đối số thực tế tương ứng 0(p)(theo môi trường, hoặc đổi tên các vấn đề, rất quan trọng nhưng sẽ làm phức tạp giải thích ở đây, và là sự khác biệt chính giữa ngôn ngữ Lisp gốc và ngôn ngữ Scheme).

Do đó bạn thay thế việc đánh giá ( test 0 (p) )bằng cách đánh giá (if (= 0 0) 0 (p)).

Bây giờ chức năng iflà một chức năng nguyên thủy mà thường luôn luôn đánh giá đối số đầu tiên của nó, nhưng đánh giá 2 đối số cuối cùng của nó để bình thường, việc đánh giá chỉ là một hữu ích, tùy thuộc vào việc đánh giá lại đầu tiên sai hoặc đúng (trên thực tế NILhoặc #fcho sai , hoặc một số khác giá trị đúng , trong trường hợp Đề án - nếu bộ nhớ của tôi không làm tôi thất vọng). Vì (= 0 0)đánh giá là đúng , đánh giá số tiền có điều kiện để đánh giá đối số thứ hai chưa được đánh giá 0, điều này không có gì đáng ngạc nhiên (ngoại trừ trong Fortran cũ) đánh giá 0.

Thở sâu.


Tôi nghĩ OP nhầm lẫn với định nghĩa trong chương 1 theo điều này
SMA
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.