Tại sao từ khóa rec cần thiết trong F #?


28

Trong F # cần sử dụng rectừ khóa. Trong Haskell, không cần phải nói rõ ràng nếu một hàm đã cho có đệ quy hay không.

Với vai trò của đệ quy trong lập trình chức năng, thiết kế F # có vẻ khá kỳ lạ đối với tôi. Đó có phải là một quyết định thiết kế ngôn ngữ tốt hay nó chỉ tồn tại vì lý do lịch sử hoặc vì một ràng buộc thực hiện?

Câu trả lời:


16

Có một sự khác biệt vốn có trong ngữ nghĩa Haskell và F #. Trong Haskell, một lệnh gọi hàm không thực hiện bất kỳ phép tính thực tế nào, nhưng phân bổ một đối tượng heap được gọi là 'thunk'. Hoàn toàn ổn khi một thunk có một liên kết đến chính nó hoặc một thunk khác. Tuy nhiên, trong F #, một lệnh gọi hàm là một cuộc gọi thực tế, làm cho các biểu thức như let x = 1 : 2 : x in xkhông hợp lệ - vì nó yêu cầu xphải được xây dựng trước khi 1 : 2 : xđược xây dựng. Tuy nhiên, vẫn còn ít nhiều định nghĩa hợp lý cho danh sách vô hạn, một số cách để xác định nó nên tồn tại. Đây là rễ cho rec. Nếu bạn muốn nhiều hơn, tìm kiếm và đọc các ngữ nghĩa hoạt động cho SML và Haskell - thì khác.


2
AFAIK, Haskell cố tình không có một ngữ nghĩa hoạt động.
dan_waterworth

@dan_waterworth không thể biên dịch nếu không xác định ngữ nghĩa hoạt động.
permeakra

8
Ngôn ngữ Haskell không định nghĩa một ngữ nghĩa hoạt động, mà thay vào đó cung cấp một ngữ nghĩa biểu thị. Khi bạn xây dựng một trình biên dịch, một ngữ nghĩa hoạt động được định nghĩa ngầm, nhưng điều này không có nghĩa là nó là một phần của tiêu chuẩn ngôn ngữ Haskell.
dan_waterworth

6
@dan_waterworth Trong thực tế, chỉ có một triển khai và tiêu chuẩn của ngôn ngữ Haskell: ghc, cũng như chỉ có một tiêu chuẩn F #: Microsoft thực hiện nó. Vì vậy, về mặt lý thuyết bạn có thể đúng, nhưng thực hành là con thú hoàn toàn khác nhau.
permeakra

19

Câu hỏi này đã được trả lời trên SO , và nó bao gồm một số bối cảnh lịch sử mạnh mẽ về lý do tại sao "rec" được sử dụng.

Đây là trích dẫn quan trọng cho hậu thế:

Các chức năng không được đệ quy theo mặc định trong họ ngôn ngữ CAML của Pháp (bao gồm OCaml). Lựa chọn này giúp dễ dàng thay thế các định nghĩa hàm (và biến) bằng cách sử dụng let trong các ngôn ngữ đó bởi vì bạn có thể tham khảo định nghĩa trước đó bên trong phần thân của một định nghĩa mới. F # thừa hưởng cú pháp này từ OCaml.


12

Một đệ quy letđịnh nghĩa một ngữ nghĩa phức tạp hơn đáng kể so với một ngữ nghĩa bình thường. Vì vậy, đối với một mục đích đơn giản và thiết kế ngôn ngữ sạch, có một lý do chính đáng để có cả hai, chỉ giống như có riêng biệt let, let*letrectrong Đề án.

Đơn giản let x = y in zlà tương đương với ((fun x -> z) y). Một phép đệ quy phức tạp hơn nhiều và có thể liên quan đến việc sử dụng một tổ hợp điểm cố định.

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.