Cách "bình thường" để diễn đạt hàm thuần túy là gì, là về tính minh bạch tham chiếu . Một hàm là thuần túy nếu nó trong suốt về mặt tham chiếu .
Tính trong suốt tham chiếu , đại khái, có nghĩa là bạn có thể thay thế lời gọi hàm bằng giá trị trả về của nó hoặc ngược lại tại bất kỳ điểm nào trong chương trình mà không làm thay đổi ý nghĩa của chương trình.
Vì vậy, ví dụ, nếu C printf
là trong suốt về mặt tham chiếu, hai chương trình này phải có cùng ý nghĩa:
printf("Hello");
và
5;
và tất cả các chương trình sau phải có cùng ý nghĩa:
5 + 5;
printf("Hello") + 5;
printf("Hello") + printf("Hello");
Bởi vì printf
trả về số ký tự được viết, trong trường hợp này là 5.
Nó thậm chí còn rõ ràng hơn với các void
chức năng. Nếu tôi có một chức năng void foo
, thì
foo(bar, baz, quux);
nên giống như
;
Tức là vì foo
không trả về gì, nên tôi có thể thay thế nó bằng không mà không làm thay đổi ý nghĩa của chương trình.
Vì vậy, rõ ràng là cả hai đều printf
không foo
minh bạch về mặt quy chiếu, và do đó cả hai đều không trong sáng. Trên thực tế, một void
hàm không bao giờ có thể minh bạch về mặt tham chiếu, trừ khi nó không phải là lựa chọn.
Tôi thấy định nghĩa này dễ xử lý hơn nhiều so với định nghĩa bạn đã đưa ra. Nó cũng cho phép bạn áp dụng nó ở bất kỳ mức độ chi tiết nào bạn muốn: bạn có thể áp dụng nó cho các biểu thức riêng lẻ, cho các hàm, cho toàn bộ chương trình. Ví dụ, nó cho phép bạn nói về một chức năng như thế này:
func fib(n):
return memo[n] if memo.has_key?(n)
return 1 if n <= 1
return memo[n] = fib(n-1) + fib(n-2)
Chúng ta có thể phân tích các biểu thức tạo nên hàm và dễ dàng kết luận rằng chúng không minh bạch về mặt tham chiếu và do đó không thuần túy, vì chúng sử dụng cấu trúc dữ liệu có thể thay đổi, cụ thể là memo
mảng. Tuy nhiên, chúng ta cũng có thể nhìn vào các chức năng và có thể thấy rằng nó là referentially minh bạch và do đó tinh khiết. Điều này đôi khi được gọi là sự thuần khiết bên ngoài , tức là một chức năng có vẻ thuần khiết với thế giới bên ngoài, nhưng được thực hiện bên trong không tinh khiết.
Các chức năng như vậy vẫn hữu ích, bởi vì trong khi tạp chất lây nhiễm sang mọi thứ xung quanh nó, giao diện tinh khiết bên ngoài xây dựng một loại "rào cản độ tinh khiết", nơi tạp chất chỉ lây nhiễm ba dòng của hàm, nhưng không rò rỉ ra phần còn lại của chương trình. . Ba dòng này dễ phân tích tính đúng đắn hơn nhiều so với toàn bộ chương trình.