Có một định nghĩa kinh điển về chức năng tinh khiết của Viking không?


9

StackOverflow chỉ cho tôi ở đây, vì vậy câu hỏi có thể là một chút trong các điều khoản của giáo dân.

Wikipedia định nghĩa các hàm thuần túy

Trong lập trình máy tính, một hàm có thể được mô tả là một hàm thuần nếu cả hai câu lệnh này về hàm giữ:

  1. Hàm luôn đánh giá cùng một giá trị kết quả được đưa ra cùng (các) giá trị đối số. Giá trị kết quả chức năng không thể phụ thuộc vào bất kỳ thông tin hoặc trạng thái ẩn nào có thể thay đổi khi tiến hành thực hiện chương trình hoặc giữa các lần thực hiện khác nhau của chương trình, cũng không thể phụ thuộc vào bất kỳ đầu vào bên ngoài nào từ các thiết bị I / O.
  2. Đánh giá kết quả không gây ra bất kỳ tác dụng phụ hoặc đầu ra có thể quan sát được về mặt ngữ nghĩa, chẳng hạn như đột biến của các đối tượng có thể thay đổi hoặc đầu ra cho các thiết bị I / O.

Tuy nhiên, nó dường như không trích dẫn bất kỳ nguồn nào - vì vậy thật khó để nói liệu đây có phải là một định nghĩa được chấp nhận hay ai đã định nghĩa nó theo cách này.

Khi tôi nhìn vào những gì các ngôn ngữ làm khi chúng bao gồm một cú pháp / chú thích cho các hàm "thuần túy", có khá nhiều cách tiếp cận khác nhau:

  1. Trong D giới hạn duy nhất là không đột biến của nhà nước toàn cầu. Các hàm "Pure" có thể làm thay đổi các đối số của nó.
  2. Trong GCC có hai loại "thuần túy": pure(không có tác dụng phụ, nhưng có thể đọc trạng thái toàn cầu) và const(hoàn toàn thuần túy theo định nghĩa của wikipedia).
  3. Trong C # , nó được định nghĩa là "không thực hiện bất kỳ thay đổi trạng thái hiển thị nào" (bất kể đó là gì).
  4. Haskell tuân theo định nghĩa Wikipedia.

Vì vậy, câu hỏi của tôi là: có một định nghĩa chính tắc của chức năng thuần túy?
Và nếu có, nguồn của nó là gì?


Quan điểm lịch sử liên quan, mặc dù dường như không ai đưa ra bất kỳ câu trả lời xác định hoặc có nguồn gốc.
Guildenstern

1
Đây không phải là câu trả lời nhưng đây là định nghĩa của tôi: nếu x = y (theo định nghĩa của nó) thì fx = fy là đúng và f không gây ra thay đổi bên ngoài về trạng thái (nghĩa là tất cả thay đổi trạng thái là nội bộ đối với x, y, và f). Haskell tận dụng lợi thế này. Nó thực hiện đánh giá lười biếng bằng cách thay đổi thunks và thay thế chúng bằng các hàm trả về kết quả ngay lập tức. Đó là nếu bạn đánh giá (fx) nó thực sự có thể thay đổi f và x dưới mui xe nhưng bạn không bao giờ có thể nói.
Jake

Câu trả lời:


3

Như đã lưu ý trong bài viết này Lập trình chức năng bắt buộc , (1993) của Peyton-Jones và Wadler (trong nhóm các nhà nghiên cứu đã tạo ra Haskell):

Chúng tôi tập trung vào các giải pháp hoàn toàn chức năng, loại trừ tác dụng phụ, vì hai lý do. Thứ nhất, việc không có tác dụng phụ cho phép sử dụng không hạn chế lý luận và chuyển đổi chương trình ...

trọng tâm là không có các hiệu ứng phụ để cho phép chuyển đổi chương trình (tức là tối ưu hóa trình biên dịch).

Tác dụng phụ là gì? Bài viết này lần lượt chỉ ra việc tích hợp lập trình chức năng và mệnh lệnh (1986) của Gifford và Lucassen, trong đó đề cập đến bốn loại lớp hiệu ứng : Tinh khiết, Chức năng, Quan sát viên và Thủ tục. Vì vậy, thuật ngữ "hàm thuần túy" xuất phát từ bài báo này.

  • PURE được minh bạch về mặt tham chiếu: nó không gây ra tác dụng phụ, giá trị của nó không bị ảnh hưởng bởi tác dụng phụ và nó trả về cùng một giá trị mỗi lần đánh giá.

Tuy nhiên, lưu ý rằng Peyton-Jones và Wadler đã đề cập đến những thiếu sót trong phương pháp này. Đáng chú ý, họ nói, là ngôn ngữ lập trình Clean sử dụng các loại tuyến tính để giới thiệu các hiệu ứng phụ theo cách an toàn (nghĩa là an toàn cho trình biên dịch). Về cơ bản, nó xử lý Thế giới như một biến trong tất cả các chức năng liên quan đến I / O, bao gồm cả hàm chính điểm vào .

Cùng với đó, có thể có một ngôn ngữ chức năng thuần túy tương tác với thế giới và có tác dụng phụ (I / O, HĐH, hệ thống Windowing, v.v.), trái ngược với một phần định nghĩa wikipedia của bạn. Thực tế người ta có thể nói rằng Haskell có Clean là một trong những người có ảnh hưởng; mặc dù nó khởi hành từ các loại tuyến tính và sử dụng một cấu trúc cấp loại khác (monads) để đảm bảo tính tuyến tính, tức là một tham chiếu đơn lẻ mọi lúc.


"Về cơ bản, nó tạo ra Thế giới như một biến số ...". Bạn có thực sự có nghĩa là "chủ đề". Có một tài khoản không chính thức về điều này trên web?
babou

Tôi đã sử dụng "luồng" như một phép ẩn dụ. Điều đó có nghĩa là, bạn phải truyền biến Thế giới từ hàm này sang hàm khác. Và gõ tuyến tính có nghĩa là biến Thế giới như vậy không được sử dụng nhiều hơn một lần. Nó ngụ ý, ví dụ, để mở một tệp bên trong một chức năng bạn sẽ làm như thế (f_handle, world2) = fopen file_name, world(mã giả) và một cuộc gọi tiếp theo sẽ phải sử dụng world2. Về bản chất, các chương trình được xem là hoạt động trên toàn vũ trụ . Nói cách khác, không có tác dụng phụ khi bạn hoạt động trên Vũ trụ :-)
carlosayam

Luồng thế giới, như bạn nói, dường như là cách tiêu chuẩn (như tôi nhớ lại) để đối phó với môi trường trong ngữ nghĩa học biểu thị. Vì vậy, điểm quan trọng phải là tuyến tính. Nhưng sau đó, ngữ nghĩa học biểu thị (DS) được cho là hoàn toàn có chức năng, không có bất kỳ ràng buộc tuyến tính nào. Tôi đoán DS là một sự trừu tượng toán học và không có ý định về việc tung hứng nhiều thế giới. Điện toán là vật lý và tuyến tính cho phép tiến hóa thế giới, nhưng chỉ một Thế giới có thể tồn tại cùng một lúc (có thể đánh giá tuần tự). Ngữ nghĩa của 2 chương trình Clean chạy đồng thời là gì :-)?
babou

Giấy Gifford và Lucassen có thể truy cập trên web không?
babou

Tôi đã truy cập thông qua Uni.
carlosayam

-1

Định nghĩa của Wikipedia là kinh điển. Hai yêu cầu quan trọng là:

  • Giá trị trả về và hành vi của hàm là một hàm xác định của các đối số được truyền rõ ràng cho hàm.

  • Một lời gọi của chức năng không có tác dụng phụ có thể quan sát được.

Nói đúng ra, D và gcc không nên sử dụng từ "thuần túy" theo cách họ làm; đó là sự lạm dụng thuật ngữ tiêu chuẩn.

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.