* Bất kỳ * nhiệm vụ chương trình có thể được thể hiện mà không có nhà nước?


13

Đây là một câu hỏi lý thuyết, nhưng sau nhiều năm lập trình theo cái mà bây giờ tôi nhận ra là kỹ thuật bắt buộc "bình thường", sử dụng C ++ là chủ yếu, tôi đã phát hiện ra thế giới lập trình chức năng khác, tình cờ tôi tình cờ tìm hiểu JavaScript.

Điều này đã khiến tôi tự hỏi liệu bạn có thể thay thế về mặt kỹ thuật bất kỳ chương trình định hướng nhà nước hoàn chỉnh nào bằng một triển khai khác hoàn toàn là chức năng và không có nhà nước không?

Đó là một ý tưởng hấp dẫn và tôi phải thừa nhận rằng có một sự rõ ràng và thanh lịch trong lập trình chức năng đã thực sự làm tôi suy nghĩ.


1
Câu trả lời StackOverflow có liên quan: stackoverflow.com/questions/3722084/ từ
jfriend00

Có hay không có trạng thái tồn tại từ thời điểm này đến thời điểm tiếp theo không phụ thuộc vào mô hình lập trình bạn sử dụng, mà phụ thuộc vào vấn đề hoặc nhiệm vụ bạn đang mã hóa. Nếu bạn đang đếm số lần nhấp vào nút, thì rõ ràng có trạng thái để ghi lại bộ đếm đó và không quan trọng bạn sử dụng kỹ thuật mã hóa nào, sẽ phải có trạng thái theo dõi số đếm trong quá trình. Vì vậy, nhiệm vụ cụ thể đó không thể được hoàn thành mà không có trạng thái trên đường đi cho dù bạn viết mã như thế nào.
jfriend00

6
Nếu bạn muốn thảo luận về nhà nước; rõ ràng là cần thiết, nếu chỉ cho chính chương trình. Có vẻ như bạn đang nghĩ về trạng thái có thể thay đổi so với trạng thái bất biến - bạn có thể muốn cho biết ý của bạn trong câu hỏi.
Billy ONeal

1
Điều đó giống như hỏi liệu tất cả các chương trình có thể được chuyển đổi thành máy Turing thực sự hay không. Về mặt kỹ thuật có, ngay cả các chương trình lưu và tải từ cơ sở dữ liệu tuy nhiên việc mô phỏng hành vi này trong máy Turing trở nên khó khăn hơn. Tương tự như vậy, bạn có thể có một chương trình có mặt bộ điều khiển trong kiến ​​trúc MVC bị loại bỏ và bạn thực hiện tất cả các cuộc gọi, mặc dù vậy, nó trở nên khó xử lý hơn (về cơ bản bạn trở thành bộ điều khiển để làm cho chương trình không trạng thái).
Neil

Câu trả lời:


17

Câu trả lời ngắn gọn: có. Theo Wikipedia, sự tương đương của phép tính lambda với các máy Turing như một mô hình tính toán phổ quát được thể hiện vào năm 1937 bởi Alan Turing. Mô hình tính toán của máy Turing là những gì bạn thường nghĩ đến khi nói về lập trình cấp bách hoặc trạng thái, và phép tính lambda là một phép toán chính thức về "lập trình hàm thuần túy".

Người ta cho rằng mọi mô hình tính toán hiệu quả đều có thể thực hiện các phép tính giống như máy Turing và ngược lại. Đây được gọi là luận án Church-Turing . Tuy nhiên, sự dự đoán này không thể được chứng minh, vì thuật ngữ "mô hình tính toán hiệu quả" ít nhiều trực quan (có lẽ ai đó sẽ phát minh ra một mô hình mới trong tương lai?)


2
Lập luận tương tự của bạn có thể được hoàn nguyên khi nói rằng tính toán lamba tương đương với máy du lịch, mọi tính toán phải có trạng thái (ít nhiều bị ẩn). Cho dù được biểu diễn bên ngoài mã (bằng phương tiện của biến) hay bên trong luồng (bằng phương thức gọi hàm dựa trên ngăn xếp) luôn luôn là "trạng thái".
Emilio Garavaglia

3
Tính toán Lambda có trạng thái; hạn chế của nó là nhà nước là bất biến. Nhà nước bất biến vẫn là nhà nước. Các tham số cho các chức năng, bao gồm lambdas, vẫn ở trạng thái; có lẽ bạn muốn một hàm có hành vi khác nhau được cung cấp các tham số khác nhau.
Billy ONeal

@emilio Nói rằng có một giải pháp dựa trên trạng thái tương đương cho một vấn đề (như bạn mô tả) không phải là bằng chứng cho thấy không có phiên bản không trạng thái nào của giải pháp đó tồn tại.
Billy ONeal

2
@EmilioGaravaglia sau đó bạn đang đề cập đến trạng thái của một trình thông dịch lambda-tính toán. Khi suy luận trong phép tính lambda, không cần phải suy luận về trạng thái. Ngoài ra, khía cạnh của "Mutility" là khác nhau.
wirrbel

1
@EmilioGaravglia: Trạng thái trong lập trình mệnh lệnh là cấu hình bộ nhớ tại một thời điểm, ở đây không gian tham số được cung cấp bởi tất cả các giá trị bộ nhớ có thể và trạng thái là một cấu hình tại một thời điểm (dải của máy xử lý). Khi viết chương trình trong phép tính lambda, không có thực thể trực tiếp như trường bộ nhớ. Thực hiện chương trình là ứng dụng của biến đổi lambda. Các bước trung gian có thể giống với "trạng thái", nhưng chúng chỉ là các biểu thức tương đương có cùng giá trị. Không có gì thay đổi trong quá trình đánh giá, các biểu thức chỉ được viết lại và xử lý thành một dạng "đơn giản hơn".
wirrbel

14

Trong bất kỳ hệ thống động nào, "trạng thái" là thứ khiến cho hiện tại của bạn bị ảnh hưởng bởi quá khứ hoặc tương lai của bạn (mũi tên thời gian không phải là vấn đề toán học, chỉ là một ràng buộc vật lý).

Cho dù bạn có một cái gì đó để "nhớ" hoặc điều đó phụ thuộc vào những gì bạn đã làm, bạn có một trạng thái.

Một hệ thống không có trạng thái không "động": nó chỉ là một hàm tổ hợp. Điều đó có thể không có trạng thái, nhưng - để tạo ra các kết quả khác nhau - cần một trạng thái được cung cấp bằng cách nào đó.

Bây giờ, tùy thuộc vào mô hình tính toán mà bạn đề cập, một trạng thái có thể được biểu diễn rõ ràng (dưới dạng biến) hoặc ngầm (dưới dạng "địa chỉ trả về").

khi bạn làm fna(fnb(x))bạn đang đưa ra một trạng thái cho fnb thì đến lượt nó sẽ tạo ra một trạng thái cho fna. Điều này là do thực tế xtồn tại trước khi fnb được gọi (vì vậy, nó xuất phát từ "quá khứ" của chính nó).

Đây không phải là vấn đề "trạng thái tồn tại" hay "trạng thái không tồn tại". Đó là một vấn đề của "Tôi quan tâm" hoặc "Tôi không".


0

Nhà nước có nghĩa là khả năng đáp ứng với một kích thích hiện tại theo cách phụ thuộc vào các kích thích trong quá khứ, không chỉ dựa trên các kích thích hiện tại.

Các chương trình chức năng hoàn toàn chỉ là chức năng. Do đó, đối với các ứng dụng thực tế, chương trình chức năng thuần túy nhập một cặp (old_state * Present_stimulus) và xuất ra một cặp (new_state * Present_response). Một "kẻ lừa đảo" bên ngoài, có trạng thái là cần thiết để chờ kích thích tiếp theo và tuyên truyền trạng thái.

Một chương trình hoàn toàn có chức năng thực chất không có trạng thái, và - không thể được sử dụng cho các ứng dụng thực tế trực tiếp.

Do đó, không có chương trình định hướng nhà nước nào có thể được thay thế bằng một triển khai khác hoàn toàn là chức năng và không có nhà nước.


0

Bạn có thể tránh trạng thái đột biến rõ ràng miễn là bạn không phải tương tác với thế giới bên ngoài.

Trong JavaScript để chương trình của bạn thực sự có hiệu ứng ngoài việc chiếm chu kỳ bộ xử lý, bạn phải sửa đổi đối tượng Dom hoặc đối tượng Window và các API này đều ở trạng thái. Nhưng tôi cho rằng bạn có thể tạo một trình bao bọc đã chuyển các đối tượng Dom và Window làm tham số cho mã JavaScript và sau đó nhận được một Dom / Window mới làm đầu ra. Điều này sẽ cô lập mã JavaScript khỏi trạng thái có thể thay đổi.

Tất nhiên bạn vẫn đang dựa vào trạng thái, vì bản chất cửa sổ trình duyệt và DOM là trạng thái. Bất kỳ ứng dụng tương tác nào vốn đã có trạng thái, nhưng bạn vẫn có thể cấu trúc mã của mình theo cách để giảm thiểu trạng thái rõ ràng.

Một câu hỏi khác là nếu nó là một ý tưởng tốt. Ngay cả Haskell, một ngôn ngữ chức năng thuần túy theo thiết kế, bao gồm đơn vị 'trạng thái', cho phép bạn mô phỏng trạng thái có thể thay đổi. Điều này cho thấy rằng trạng thái đột biến rõ ràng đôi khi thực sự là một mô hình mong muốn.


0

Hãy suy nghĩ về cách bạn sẽ thực hiện một "máy trạng thái" bằng ngôn ngữ lập trình mà không có trạng thái.

Bạn có thể thực sự có thể làm điều đó nhưng cuối cùng bạn sẽ sử dụng tên hàm làm bộ lưu trữ. Kết thúc với gookblyday gook như:

if (sm.atBegining()) sm.start() else if (sm.done()) sm.stop() ) else sm.progress()
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.