Mô hình tinh thần hoặc phép ẩn dụ trong thế giới thực cho lập trình chức năng


16

Có ai có một mô hình tinh thần hay ẩn dụ tốt cho lập trình chức năng tham chiếu một cái gì đó trong thế giới thực không?

Lập trình hướng đối tượng trực giác có ý nghĩa với tôi. Có những thứ có các thuộc tính và đôi khi chúng cũng có thể thực hiện công cụ hoặc thực hiện các phép tính trên các thuộc tính (phương thức) của chúng. (Ví dụ: Xe hơi, Hình dạng, Mèo).

Tôi không có lập trình chức năng nào cả và tôi không hứng thú với một cuộc tranh luận về đức tính của hai người. Tôi chỉ cần một phép ẩn dụ hoặc mô hình tinh thần để làm việc như tôi có với lập trình Hướng đối tượng.

Một số mô hình tinh thần tốt hoặc ẩn dụ trong thế giới thực để lập trình trong một mô hình chức năng là gì? Có một cái gì đó về các chức năng bao gồm các chức năng xử lý các chức năng khiến cho một người không có chỗ đứng vững chắc và hợp tác.


Ý nghĩa cụ thể nào của "lập trình chức năng" mà bạn đang đề cập đến, "không có tác dụng phụ / khai báo" hay "chức năng hạng nhất / thành phần chức năng"? Hoặc cả hai?
acelent

Câu hỏi thú vị. Với kiến ​​thức nhỏ hiện tại của tôi và ít kinh nghiệm lập trình trong "lập trình chức năng", tôi không thể trả lời một cách có ý nghĩa câu hỏi đó. Nếu tôi muốn đoán, tôi sẽ nói cả hai.
Guido Anselmi

13
Mô hình "thế giới thực" thường được đưa ra như một động lực cho lập trình hướng đối tượng. Tôi nghĩ rằng đó là một cách tiếp cận cuối cùng bạn nên phát triển, bởi vì các đối tượng trong OOP không phải lúc nào cũng tương ứng với các đối tượng trong thế giới thực và ngay cả khi chúng thực hiện, sự tương ứng thường không đầy đủ; ví dụ, các mối quan hệ "is-a" không phải lúc nào cũng giống nhau. Mặt khác, một khi bạn nói rằng bạn muốn một mô hình hoặc phép ẩn dụ cho ngôn ngữ lập trình dựa trên một cái gì đó trong "thế giới thực", tôi nghĩ rằng về cơ bản bạn đã giới hạn bản thân trong hình thức OOP giới hạn này.
David K

Một mô hình tinh thần thực sự tốt, nếu bạn có kinh nghiệm sử dụng các hệ thống giống như unix (hoặc quyền hạn trong Windows hiện đại) là vỏ một lớp. Chúng không hoàn toàn giống nhau vì các ống vỏ là lập trình dựa trên dòng chảy kỹ thuật thay vì chức năng nhưng chúng có cùng "cảm giác" như một lập trình viên.
slebetman

1
Ngoài ra, bạn sẽ thấy khi bạn học các ngôn ngữ chức năng, trong lập trình hướng đối tượng chức năng được coi là một công cụ, như các biểu thức thông thường chẳng hạn. Một cái gì đó bạn có thể sử dụng nếu bạn thích nhưng bạn không phải. Trong một số ngôn ngữ như lisp và tcl và OO không phải là một tính năng tích hợp với ngôn ngữ mà là một thư viện mà bạn có thể sử dụng (hoặc thậm chí bạn có thể viết OO của riêng mình nếu bạn cảm thấy dũng cảm). Vì vậy, các vấn đề tự nhiên có giải pháp OO có thể được giải quyết bằng OO trong hầu hết các ngôn ngữ chức năng. Mọi người chỉ không coi OO là một tôn giáo.
slebetman

Câu trả lời:


32

Lập trình chức năng là tất cả về việc dán các chức năng nhỏ hơn với nhau để đạt được kết quả của bạn. Một mô hình tinh thần tốt (đối với tôi, ít nhất) là một dây chuyền lắp ráp. Mỗi chức năng được sáng tác là một bước nữa trong quy trình lắp ráp. Xem xét chức năng này ở đây:

smallest  = head . sort

Trong Haskell, hàm này sẽ trả về phần tử nhỏ nhất trong danh sách. Đầu tiên, dây chuyền lắp ráp sắp xếp đầu vào, sau đó trả về phần tử đầu tiên (giả sử nó được sắp xếp ít nhất đến lớn nhất.) Nếu chúng ta chỉ muốn nhận giá trị chẵn nhỏ nhất, thì chúng ta có thể thay đổi dây chuyền lắp ráp như sau:

smallestEven = head . sort . filter even

Nó chỉ là một bước nữa trên băng chuyền.

Tóm lại, các hàm chỉ mô tả các bước được thực hiện để chuyển đổi đầu vào thô (các bộ phận) thành hàng hóa được xử lý (đầu ra.)


2
Trong một ngôn ngữ chức năng thuần túy không có biến toàn cục, thì một dây chuyền lắp ráp không thể ảnh hưởng đến dây chuyền kia (trừ khi nó cung cấp đầu vào dòng khác.) Về mặt lý thuyết, bất kỳ dây chuyền lắp ráp nào không phụ thuộc vào nhau đều có thể được thực thi song song, nhưng tôi không chắc chắn nếu bất kỳ trình biên dịch làm điều này.
bstamour

3
@GuidoAnselmi Một cách để nghĩ về nó là dây chuyền lắp ráp trong lập trình chức năng xây dựng các đầu ra mới trong khi vẫn giữ nguyên các đầu vào, trong khi dây chuyền lắp ráp trong OOP truyền thống biến đổi đầu vào.
Doval

2
Ẩn dụ này chỉ có ý nghĩa trong "chức năng / thành phần chức năng hạng nhất" có nghĩa là "lập trình chức năng", chứ không phải trong "không có tác dụng phụ / khai báo". Ngoài ra, lập trình hướng đối tượng không nhất thiết phải có tác dụng phụ, vì vậy bạn có thể triển khai một dây chuyền lắp ráp phá hoại hoặc mang tính xây dựng với OOP hoặc ý nghĩa này của FP. OOP thiên về đóng gói, truyền thông điệp và đa hình hơn là về tác dụng phụ, nó phụ thuộc vào cách bạn mô hình hóa mọi thứ. Ví dụ, bạn yêu cầu danh tính giới thiệu từ đầu đến cuối?
acelent

3
@bstamour: Để chính xác, người ta nên viết (f . g) (x)có nghĩa là f(g(x))hoặc f . gphương tiện \x -> f (g (x)).
Giorgio

3
@MarjanVenema Things luồng còn lại trong ví dụ mà chỉ vì đó là cách .được xác định; Đây không phải là cách Haskell hoạt động nói chung . Bạn cũng có thể xác định toán tử đường ống chuyển tiếp ( |>) của F # trong Haskell và ghi smallest x = (sort x) |> headvà dữ liệu sẽ chảy đúng. Chỉ cần nghĩ rằng tôi chỉ ra rằng.
Doval

18

Có ai có một mô hình tinh thần tốt cho lập trình chức năng?

Toán học. Lập trình hàm được lấy cảm hứng và mô hình hóa trên toán học. Các hàm toán học không có trạng thái, không có tác dụng phụ, v.v., và đó là với FP. Nếu bạn nghĩ về FP về các chức năng toán học thay vì sử dụng cách tiếp cận "làm thế nào để làm điều đó" theo kiểu OO, bạn sẽ có một hình dạng tốt. Tuy nhiên, nếu bạn cố gắng mang lại sự nhạy cảm OO cho FP, bạn sẽ bơi ngược lại hiện tại.


1
Cảm ơn. Tuy nhiên, tôi cần một phép ẩn dụ từ thế giới thực (ví dụ không phải từ máy tính hoặc toán học).
Guido Anselmi

3
@GuidoAnselmi: Một chức năng là một hộp đen. Bạn đặt một cái gì đó vào một bên và sau đó một cái gì đó mới xuất hiện ở phía bên kia. Nếu bạn đặt những thứ tương tự vào, bạn luôn nhận được những thứ tương tự. Bạn có thể lấy rất nhiều những chiếc hộp nhỏ này và kết hợp chúng theo các đơn đặt hàng khác nhau để xây dựng một nhà máy có thể lấy kim loại thô và sản xuất một chiếc xe hơi. Bên trong quá trình được chia thành nhiều mảnh, nhưng từ bên ngoài nó chỉ là một chức năng khác.
Daenyth

16

Làm thế nào về một cuốn sách lật ?

Trong một cuốn sách lật, mỗi trang đại diện cho thế giới như nó tồn tại tại một thời điểm. Trong chương trình của chúng tôi, thế giới được thể hiện dưới dạng một số cấu trúc dữ liệu hỗn hợp (ví dụ: chúng ta có một quả chuối nằm trong tay một con khỉ đột đang ở trong một cái cây trong rừng rậm). Mỗi trang tiếp theo tiến bộ câu chuyện bằng cách sửa đổi một chút đại diện trước đó. Trong FP, các cấu trúc dữ liệu liên tục được thiết kế để tái sử dụng hiệu quả các cấu trúc trước đó để thay đổi chỉ cung cấp một delta và không phải là biểu hiện hoàn toàn mới.

Điều có thể không rõ ràng là một trang trong cuốn sách lật của chúng tôi cũng sẽ đại diện cho các tài liệu vô hình. Ví dụ, nếu con khỉ đột làm rơi quả chuối, chúng ta có thể bắt đầu áp dụng các tác động của trọng lực lên sự tươm tất của nó và tăng tốc về phía sàn rừng. Để phù hợp với điều này, chúng tôi sẽ đính kèm các thuộc tính như vận tốc và quỹ đạo vào quả chuối của chúng tôi.

Trong chương trình của chúng tôi sẽ có một chức năng chấp nhận một trang sách lật (còn gọi là trạng thái của thế giới) làm đối số và mang lại một trang mới . Theo cách này, câu chuyện của chúng tôi được kể mà không bao giờ thực sự thay đổi trạng thái của các đối tượng hiện có. Chúng tôi chỉ đơn giản thay thế mỗi trang bằng một trang mới hơn bằng cách sử dụng tính toán một cách hiệu quả.


3

Các mối quan hệ.

Bạn bè: Cho hai người, một mối quan hệ bạn bè tuân theo các luật chung này

  1. Có thiện chí với nhau
  2. Nghĩ rằng nhau là một người bạn với họ (vì vậy luật pháp phải được thực hiện bởi cả hai thành viên trong mối quan hệ này)
  3. Thích dành thời gian cho nhau

Monoid: Cho nhiều mục và một hàm lấy 2 trong số các mục và trả về 1, một mối quan hệ đơn hình tuân theo các quy luật chung này

  1. Có một trong những mục đó (chỉ một, được gọi là danh tính) được truyền cho hàm với bất kỳ mục nào khác sẽ đảm bảo hàm luôn trả về mục khác (0 + 1 = 1, do đó 0 là danh tính khi các mục là số và chức năng là bổ sung)
  2. Hàm không thể hoạt động trên hoặc trả về các mục không có trong tập hợp, nó có mối quan hệ đơn hình với
  3. Hàm này có tính kết hợp và có thể được sử dụng với các mục theo cách độc lập theo thứ tự, điều này có nghĩa là a * (b * c) = (a * b) * c nói rằng bạn có thể nhân a với kết quả của b * c hoặc c bởi kết quả của một * b và kết quả sẽ giống như bất cứ điều gì bạn làm trước tiên.

Lập trình hàm là tất cả về khái quát hóa, bạn bè là một mối quan hệ rất chung có thể được nhìn thấy trong nhiều tình huống, nhưng trong tất cả các định dạng khác nhau, nó thường tuân theo các quy định ở trên.

Nhận thức được các luật chi phối các mối quan hệ giữa các sự vật, bạn có thể tạo ra các triển khai chung hoạt động trên bất kỳ định dạng nào của những thứ có loại mối quan hệ đó. Trong lập trình chức năng, bạn cố gắng xác định mối quan hệ giữa các thứ để chúng có thể được phân loại và xử lý chung.

Bạn muốn một phép ẩn dụ từ thế giới thực? Nhìn vào cách mọi thứ có liên quan và cố gắng xác định các luật chung (như áp dụng cho nhiều tình huống trong đó những điều khác với luật có thể khác nhau). Có một mối quan hệ giữa một nhân viên đăng ký và một người mua hàng tại một cửa hàng, nó có một số luật chung, phần mềm đã được phát triển để tạo thuận lợi cho các mục tiêu của mọi người trong mối quan hệ chung đó theo cách của hệ thống POS. Tương tự như vậy khi bạn bắt đầu nhìn thấy những luật chung này chỉ ra cách mọi thứ liên quan, bạn có thể bắt đầu dựa vào luật của những mối quan hệ đó bằng cách viết phần mềm của bạn chứ không phải là những chi tiết cụ thể của một mối quan hệ.


2

Mọi thứ đều là giá trị và bạn áp dụng các hàm cho các giá trị (có thể là hàm) để tạo ra các giá trị mới, tốt nhất là không tạo ra bất kỳ tác dụng phụ nào.


Cảm ơn. Thật không may, điều đó nghe giống như một mô tả sau đó mô hình tinh thần hoặc ẩn dụ. Tôi cần một phép ẩn dụ từ thế giới thực (không phải từ máy tính).
Guido Anselmi

1
Như Caleb chỉ ra , lập trình mô hình chức năng toán học, không phải thế giới thực. Nó có thể mô hình hóa thế giới thực thông qua lăng kính toán học, nhưng bạn có thể sẽ không tìm thấy một phép ẩn dụ nào thỏa mãn bạn, bởi vì FP tránh xa khái niệm về những thứ có bản sắc và trạng thái đột biến. Nếu bạn thích, tôi có thể chỉ ra cách OOP xây dựng bản đồ cho FP, nhưng đó vẫn không phải là câu trả lời bạn muốn.
Doval

Nhưng toán học dựa trên thế giới thực. 1 mặt trời, 9 hành tinh. 2 quả táo cộng với 2 quả táo làm cho bốn quả táo.
Guido Anselmi

Và trong lập trình chức năng, bạn cũng có thể có một loại cho mặt trời, hành tinh và táo, sau đó tạo một giá trị của loại mặt trời, 9 giá trị của loại hành tinh và xác định bổ sung cho loại táo.
Doval

3
@GuidoAnselmi bạn có nó hoàn toàn ngược, mọi người phân tích thế giới thực bằng toán học, nó không có cơ sở trên thế giới thực. Toán học được sử dụng để phân tích và xác định mối quan hệ giữa tất cả các loại, thực và không. 9 hành tinh là bạn áp dụng một cấu trúc toán học (tập hợp các số tự nhiên) cho một cấu trúc trong thế giới thực (các hành tinh) với chức năng phân tích toán học (đếm). Thế giới thực không có 9 hành tinh, nó có những gì nó có, toán học chỉ nói về những biểu tượng tượng trưng của những thứ trong đó các biểu tượng có mối quan hệ giữa nhau.
Jimmy Hoffa

1

Điều quan trọng để nhận ra về lập trình chức năng là mọi thứ đều là giá trị - ngay cả bản thân mã cũng là 'giá trị'.

Ví dụ tốt nhất về môi trường lập trình chức năng đơn giản là công cụ kinh doanh yêu thích của mọi người - bảng tính. Mỗi ô trong bảng tính là dữ liệu hoặc kết quả của hàm. Hơn nữa, chức năng này không thể tắt và sửa đổi một ô khác.

Khi một người di chuyển đến một ngôn ngữ chức năng, thay vì một lưới Descartes của A1B42, các chức năng có tên. Đó là tất cả những gì nó thực sự là.

Có những khía cạnh khác mà người ta có thể thêm vào ngoài điều này ... nhưng đó là lập trình chức năng ở cốt lõi của nó. Bạn không cần phải lo lắng về cấu trúc của danh sách hoặc nhóm các thứ. Lập trình hàm là về việc chuyển một giá trị vào một hàm và lấy lại giá trị mà không có bất kỳ sự lột xác nào về bộ nhớ.

Đó là nó. Lập trình hàm là một bảng tính có tên chứ không phải là lưới.


0

Bạn có thể nghĩ về lập trình chức năng như về các hành vi . Một chương trình là một mô tả về hành vi mà bạn muốn máy tính ban hành. Hàm là đơn vị cơ bản của hành vi và thành phần chức năng là một cách để xây dựng các hành vi lớn hơn từ các hành vi nhỏ hơn.

Trong OOP, một đối tượng mã được dự định trạng thái của một đối tượng trong miền vấn đề; nó thay đổi theo thời gian để phản ánh những thay đổi trong đối tượng miền đó. Trong FP, một giá trị đại diện cho trạng thái của một đối tượng miền; nó không bao giờ thay đổi, bạn chỉ cần tạo các giá trị khác nhau để thể hiện các trạng thái khác nhau.

Tôi thấy mô hình chức năng trung thực hơn một chút về những gì máy tính thực sự đang thực hiện. Rốt cuộc, tôi không thể gợi new Tesla()ra một luồng không khí mỏng. :)


-5

Các câu có nhiều chức năng hơn hướng đối tượng, giả sử bạn chia nhỏ chúng ít nhiều như sau ...

The brown cow is in the meadow across the deep river.

Vì vậy, chúng ta cần tìm các cụm từ đầu và phần còn lại:

The cow (brown)
the meadow (across)
the river (deep)

Chỉ trong một bước:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Cây phân tích:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Parsimony lây nhiễm suy nghĩ chức năng;

Ngả mũ trước Gottlieb Frege 1890s, Alan Turing (entschiedungsprobleme) những năm 1930, Noam Chomsky (thập niên 1960).


4
Đây là một lời giải thích khó hiểu và tôi bắt đầu quen thuộc với FP.
Daenyth

Trông giống như bắt chước hình thức của Lisp mà không hiểu ý nghĩa
Izkata
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.