Lập trình chức năng ngày càng tăng?


42

Gần đây tôi đã nhận thấy rằng các ngôn ngữ lập trình chức năng đang trở nên phổ biến . Gần đây tôi đã thấy cách Tiobe Index cho thấy sự phổ biến của họ so với năm ngoái mặc dù hầu hết trong số họ thậm chí không đạt được 50 ngôn ngữ phổ biến nhất theo chỉ số này.

Và điều này đã xảy ra trong một thời gian khá dài. Lập trình hàm đơn giản là không trở nên phổ biến như các mô hình khác (tức là lập trình hướng đối tượng).

Tuy nhiên, tôi đã thấy sự quan tâm trở lại đối với sức mạnh của lập trình chức năng, và bây giờ, đa lõi ngày càng phổ biến hơn, các nhà phát triển đã bắt đầu quan tâm đến các mô hình đồng thời khác đã được khám phá trước đây bởi các ngôn ngữ như Haskell và Erlang.

Tôi thấy rất quan tâm đến thực tế là mặc dù họ không có sự chấp nhận của cộng đồng đáng kể, ngày càng có nhiều ngôn ngữ thuộc loại này tiếp tục xuất hiện. Clojure (2007), Scala (2003), F # (2002) chỉ là ba ví dụ của thập kỷ gần đây.

Bản thân tôi đã đầu tư thời gian để học Haskell và Scala. Và tôi tìm thấy tiềm năng lớn trong mô hình mà đối với tôi là mới mặc dù đã ở ngoài đó quá lâu.

Và tất nhiên, câu hỏi lớn nhất của tôi là liệu có ai trong số này sẽ trở nên đủ phổ biến để xem xét đưa bất kỳ nỗ lực nào vào họ hay không, nhưng đây là câu hỏi mà ngay cả Mandrake cũng không thể trả lời, mặc dù tất cả những người ồn ào đang làm về họ.

Điều tôi muốn hỏi là:

  • Trong trường hợp nào tôi nên xem xét một ngôn ngữ lập trình chức năng phù hợp hơn để thực hiện một nhiệm vụ nhất định? Bên cạnh vấn đề đa lõi phổ biến gần đây của lập trình song song.
  • Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn sẽ coi là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt? (Bên cạnh thay đổi mô hình và khó đánh giá hiệu suất do đánh giá lười biếng).
  • Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

Bất kỳ khuyến nghị cho nghiên cứu tiếp theo sẽ được chào đón nhiều hơn.

Tôi đã tìm kiếm trên mạng các ý kiến, và có vẻ như tất cả sự phổ biến đổi mới này xuất phát từ ý tưởng rằng bây giờ chúng ta sắp sửa vượt qua Luật Moore và các ngôn ngữ lập trình chức năng sẽ đến và cứu chúng ta một cách anh hùng. Nhưng nếu đây là trường hợp, tôi sẽ nói có nhiều xác suất của các ngôn ngữ phổ biến hiện có thích ứng với mô hình.

Một số bạn, với nhiều kinh nghiệm làm việc mỗi ngày với các ngôn ngữ này có lẽ, có thể cung cấp cái nhìn sâu sắc hơn về chủ đề này. Tất cả các ý kiến ​​của bạn sẽ được đánh giá tốt hơn và xem xét cẩn thận.

Cảm ơn trước!


4
Đó là Erlang, không phải Earlang (Tôi đã chỉnh sửa bài đăng của mình, nhưng Hệ thống không cho phép chỉnh sửa 1 chữ cái).
quant_dev

6
Đáng nói - không có ranh giới cứng giữa ngôn ngữ chức năng và mệnh lệnh. Các ngôn ngữ gia đình ML không có tác dụng phụ, và hỗ trợ các câu lệnh và cấu trúc bắt buộc và các biến có thể thay đổi. Một số ngôn ngữ bắt buộc - ngoài đầu Python và Javascript - có các tính năng quan trọng được lấy từ lập trình chức năng. Cá nhân, tôi hy vọng sẽ thấy nhiều ý tưởng chức năng hơn trong sử dụng chính - đặc biệt là khớp mẫu.
Steve314

1
Có một vài tính năng phổ biến cho các ngôn ngữ chức năng không nhất thiết phải tạo ra một ngôn ngữ "chức năng". Lập trình chức năng cũng giống như cách suy nghĩ và thiết kế chương trình cũng như về các tính năng ngôn ngữ cụ thể.
mipadi

2
@mipadi - và do đó bạn có thể áp dụng triết lý chức năng trong bất kỳ ngôn ngữ nào, ở mức độ mà các công cụ có sẵn cho phép. Bạn có thể viết mã kiểu chức năng bằng Python (trong giới hạn) và đến mức đó Python là ngôn ngữ chức năng. Và bạn có thể viết mã kiểu bắt buộc trong ML, và đến mức đó ML là một ngôn ngữ bắt buộc. Điều này không hoàn toàn giống như "các lập trình viên xấu có thể viết Fortran bằng bất kỳ ngôn ngữ nào", mặc dù rõ ràng đó là một cái bẫy dễ rơi vào nếu bạn hiểu sai quan điểm của tôi.
Steve314

1
@mipadi - nhưng nếu ngôn ngữ mệnh lệnh có tất cả các cấu trúc chức năng thông thường, bạn có thể làm bất cứ điều gì với ngôn ngữ chức năng - khoảng cách sẽ được đóng lại và câu hỏi sẽ là "cách tốt nhất để làm điều này" hơn là "những gì chức năng / mệnh lệnh". Gia đình ML đã thu hẹp khoảng cách đó, thực sự, nhưng vì nó được gọi là chức năng, chúng tôi nghĩ phong cách của nó là phong cách chức năng chứ không đơn giản là phong cách tốt.
Steve314

Câu trả lời:


24

Trong trường hợp nào tôi nên xem xét một ngôn ngữ lập trình chức năng phù hợp hơn để thực hiện một nhiệm vụ nhất định? Bên cạnh vấn đề đa lõi phổ biến gần đây của lập trình song song.

Bất cứ điều gì liên quan đến việc tạo chuỗi các yếu tố dữ liệu dẫn xuất bằng cách sử dụng một số bước chuyển đổi.

Về cơ bản, "vấn đề bảng tính". Bạn có một số dữ liệu ban đầu và tập hợp các tính toán theo từng hàng để áp dụng cho dữ liệu đó.

Các ứng dụng sản xuất của chúng tôi thực hiện một số tóm tắt thống kê dữ liệu; Đây là tất cả các cách tiếp cận tốt nhất về chức năng.

Một điều phổ biến chúng tôi làm là hợp nhất giữa ba bộ dữ liệu quái dị. Tương tự như tham gia SQL, nhưng không khái quát. Tiếp theo là một số tính toán của dữ liệu dẫn xuất. Đây là tất cả chỉ là biến đổi chức năng.

Ứng dụng này được viết bằng Python, nhưng được viết theo kiểu chức năng sử dụng các hàm tạo và các bộ dữ liệu có tên bất biến. Đây là một thành phần của các chức năng cấp thấp hơn.

Đây là một ví dụ cụ thể của một thành phần chức năng.

for line in ( l.split(":") for l in ( l.strip() for l in someFile ) ):
    print line[0], line[3]

Đây là một cách mà lập trình chức năng ảnh hưởng đến các ngôn ngữ như Python.

Đôi khi loại điều này được viết là:

cleaned = ( l.strip() for l in someFile )
split = ( l.split(":") for l in cleaned )
for line in split:
     print line[0], line[3]

Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn cho là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt? (Bên cạnh thay đổi mô hình và khó đánh giá hiệu suất do đánh giá lười biếng).

Đối tượng bất biến là rào cản khó khăn nhất.

Thông thường, bạn sẽ kết thúc việc tính toán các giá trị tạo ra các đối tượng mới thay vì cập nhật các đối tượng hiện có. Ý tưởng rằng đó là một thuộc tính có thể thay đổi của một đối tượng là một thói quen tinh thần khó phá vỡ.

Một thuộc tính hoặc hàm phương thức dẫn xuất là một cách tiếp cận tốt hơn. Đối tượng nhà nước là một thói quen khó phá vỡ.

Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

Nó không quan trọng lúc đầu. Chọn bất kỳ ngôn ngữ để học. Khi bạn biết điều gì đó, bạn đang ở trong một vị trí cân nhắc chọn một thứ khác để phù hợp hơn với nhu cầu của bạn.

Tôi đã đọc trên Haskell chỉ để hiểu những điều Python thiếu.


5
@edalorzo: Python không được gõ yếu. Nó được gõ rất, rất mạnh. Không có toán tử cast, do đó, nó được gõ mạnh hơn Java hoặc C ++.
S.Lott

5
@ S.Lott - không giúp kiểm tra kiểu tĩnh với các công cụ tái cấu trúc IDE và các công cụ kiểu intellisense? Nếu bạn có quá trình biên dịch nền và bạn đang kiểm tra tĩnh các loại, điều đó không có nghĩa là bạn có thể tự động hóa nhiều hơn trong các công cụ của mình? Tôi đồng ý rằng nếu bạn có phạm vi bảo hiểm 100% mã trong các thử nghiệm của mình, nó sẽ nắm bắt được. Bạn phải nhận ra rằng có lẽ ít hơn 50% mã sản xuất trong doanh nghiệp thực sự có phạm vi kiểm tra đơn vị, phải không? :) Có một thế giới thực ngoài kia chúng ta phải sống.
Scott Whitlock

8
@ S.Lott "Kiểm tra kiểu tĩnh không hữu ích lắm. Sẽ không có vấn đề gì nếu kiểm tra tĩnh bởi trình biên dịch hoặc kiểm tra thời gian chạy. Bạn vẫn viết cùng một lượng mã và cùng số lượng kiểm tra đơn vị. " Ơ, không. Toàn bộ các điểm kiểm tra kiểu tĩnh là nó bắt lỗi, do đó, nó ồ ạt giảm lượng thử nghiệm cần thiết.
Jon Harrop

3
@ S.Lott "Python không được gõ yếu. Nó được gõ rất, rất mạnh." Python ngầm định giữa các kiểu số đang được gõ yếu.
Jon Harrop

3
@ Steve314 "Xét cho cùng, kiểm tra kiểu tĩnh bắt được một số lỗi phù hợp với một số quy tắc cơ bản. Kiểm tra đơn vị, về nguyên tắc, có thể bắt được tất cả các lỗi đó và nhiều lỗi khác." Không. Kiểm tra tĩnh chứng minh tính đúng đắn của một khía cạnh của chương trình. Kiểm thử đơn vị tìm cách bác bỏ tính đúng đắn nhưng không chứng minh tính đúng đắn của bất cứ điều gì. Kiểm thử đơn vị không phải là sự thay thế cho kiểm tra kiểu tĩnh cũng như bất kỳ loại bằng chứng nào khác.
Jon Harrop

23

"Chức năng" là một loạt các tính năng khác nhau, mỗi tính năng đều hữu ích độc lập và tôi thấy nó hữu ích hơn khi xem xét từng tính năng.

Bất biến

Bây giờ tôi đã quen với nó, bất cứ khi nào tôi có thể thoát khỏi việc trả lại một kết quả không thay đổi, tôi luôn cố gắng làm điều đó, ngay cả trong một chương trình hướng đối tượng. Lý do về chương trình sẽ dễ dàng hơn nếu bạn có dữ liệu loại giá trị. Thông thường bạn cần khả năng biến đổi cho những thứ như GUI và tắc nghẽn hiệu suất. Các thực thể của tôi (sử dụng NHibernate) cũng có thể thay đổi (điều này hợp lý vì chúng mô hình hóa dữ liệu được lưu trữ trong cơ sở dữ liệu).

Chức năng như các loại hạng nhất

Bất cứ điều gì bạn muốn gọi nó, đi qua các đại biểu, hành động hoặc chức năng, là một cách thực sự tiện dụng để giải quyết cả một lớp các vấn đề trong thế giới thực, như "lỗ hổng trong mô hình giữa". Tôi cũng thấy rằng việc truyền một đại biểu, hành động hoặc chức năng cho một đối tượng sẽ sạch hơn so với việc lớp đó khai báo một sự kiện và nối sự kiện đó (giả sử thông thường chỉ có một "người nghe"). Khi bạn biết có một người nghe, thì hành động gọi lại có thể được chuyển qua dưới dạng tham số hàm tạo (và được lưu trữ trong một thành viên không thay đổi!)

Có thể soạn thảo các hàm (ví dụ, biến Action<T>thành một Actioncũng khá hữu ích trong một số tình huống.

Chúng ta cũng nên lưu ý cú pháp Lambda ở đây, bởi vì bạn chỉ nhận được cú pháp Lambda khi bạn quảng bá các hàm lên các loại hạng nhất. Cú pháp Lambda có thể rất biểu cảm và súc tích.

Đơn nguyên

Phải thừa nhận rằng đây là điểm yếu của tôi, nhưng sự hiểu biết của tôi là quy trình tính toán trong F #, chẳng hạn như asyncquy trình công việc, là một đơn nguyên. Đây là một cấu trúc tinh tế nhưng rất mạnh mẽ. Nó mạnh mẽ như yieldtừ khóa được sử dụng để tạo IEnumerablecác lớp trong C #. Về cơ bản, nó đang xây dựng một bộ máy trạng thái cho bạn dưới vỏ bọc, nhưng logic của bạn có vẻ tuyến tính.

Đánh giá và đệ quy lười biếng

Tôi kết hợp chúng lại với nhau vì trong khi chúng luôn được coi là các tính năng của lập trình chức năng, chúng đã nhanh chóng chuyển sang các ngôn ngữ không bắt buộc đến mức khó có thể gọi chúng là chức năng nữa.

Biểu thức S

Tôi đoán tôi không chắc chắn nên đặt cái này ở đâu, nhưng khả năng coi mã chưa được biên dịch là một đối tượng (và kiểm tra / sửa đổi nó), chẳng hạn như Lisp S-Expressions, hoặc LINQ Expressions, theo một số cách, công cụ mạnh nhất của lập trình chức năng. Hầu hết các giao diện "thông thạo" và DSL mới, sử dụng kết hợp cú pháp lambda và Biểu thức LINQ để tạo một số API rất súc tích. Chưa kể Linq2Sql / Linq2Nhibernate nơi mã C # của bạn được "thực thi" một cách kỳ diệu dưới dạng SQL thay vì mã C #.

Đó là câu trả lời dài cho phần đầu tiên của câu hỏi của bạn ... bây giờ ...

Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn cho là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt? (Bên cạnh thay đổi mô hình và khó đánh giá hiệu suất do đánh giá lười biếng).

Cạm bẫy lớn nhất mà tôi gặp phải là cố gắng tìm ra ranh giới giữa việc sử dụng các giải pháp chức năng so với các giải pháp bắt buộc. Tuy nhiên, sau khi thử cả hai cách tiếp cận một vài lần, bạn bắt đầu cảm thấy nó sẽ hoạt động tốt hơn.

Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

Nếu bạn quen thuộc với .NET, tôi đánh giá cao F #. Mặt khác, nếu bạn quen thuộc hơn với JVM, luôn có Clojure . Nếu bạn học nhiều hơn thực tế, thì tôi sẽ đi với Common Lisp hoặc Scheme. Nếu bạn đã biết Python, tôi tin rằng có rất nhiều cấu trúc chức năng đã có sẵn ở đó.


@Scott Cảm ơn bạn đã giải thích chi tiết. Tôi đoán những gì bạn mô tả là cạm bẫy lớn nhất sẽ được đưa ra khỏi phương trình bằng cách sử dụng một ngôn ngữ lập trình chức năng thuần túy như Haskell. Đó là lý do tại sao tôi đã bắt đầu với nó, bởi vì tôi đã là một lập trình viên bắt buộc suốt đời và tôi không muốn bắt đầu với một ngôn ngữ lập trình không trong sạch và có nguy cơ không học theo cách tốt. Nếu bạn không phiền tôi hỏi một câu hỏi khác: Hai điều khiến tôi lo lắng là các công cụ và thư viện. Việc tích hợp F # với các công cụ và thư viện .Net khác tốt như thế nào?
edalorzo

Tôi không hiểu tại sao bạn gộp mã khi chạy và tạo mã thời gian chạy và kiểm tra với lập trình chức năng. Hai người không có quan hệ với nhau. Các khả năng siêu lập trình mà bạn mô tả có thể được thêm vào hầu hết mọi ngôn ngữ, chức năng hoặc không. Tôi nghĩ rằng lisp bắt đầu mã theo xu hướng dữ liệu nhưng giờ đây nó có sẵn bằng ruby ​​và các ngôn ngữ phi chức năng khác.
davidk01

1
@edalorzo - Khả năng tích hợp của F # với .NET rất tốt, chỉ có một ngoại lệ nhỏ: không có trình thiết kế GUI. Bạn khắc phục điều đó bằng cách thiết kế GUI của bạn trong một cụm C # và tham chiếu nó từ F # hoặc bằng cách tạo GUI bên trong F # chỉ bằng mã (không phải với nhà thiết kế).
Scott Whitlock

@ davidk01 - câu hỏi hay về lập trình meta. Tôi chỉ thấy rằng cú pháp lambda và lập trình meta xây dựng lẫn nhau, nhưng bạn nói đúng, chúng có thể được tách ra. Có vẻ như bạn có nhiều khả năng có được lập trình meta với ngôn ngữ chức năng.
Scott Whitlock

1
@ Hủy bỏ: Tôi nghĩ theo nhiều cách nó dễ dàng hơn - ví dụ, khi bạn không phải lo lắng về tác dụng phụ, bạn có thể sửa đổi một phần mã khi đang tự tin hơn - nó hạn chế những gì bạn phải thay đổi.
Michael K

15

Và điều này đã xảy ra trong một thời gian khá dài. Lập trình hàm đơn giản là không trở nên phổ biến như các mô hình khác (tức là lập trình hướng đối tượng).

Điều này đúng nếu bạn tính các chương trình được phát triển bởi các lập trình viên chuyên nghiệp (hoặc ít nhất là mọi người thấy mình như vậy). Nếu bạn trải rộng mạng lưới của mình để bao gồm các chương trình được phát triển bởi những người không tự coi mình như vậy, thì FP (hoặc ít nhất là lập trình theo kiểu chức năng) khá gần với OO (Excel, Mathicala, Matlab, R ... thậm chí là 'JavaScript' hiện đại ' ).

Trong trường hợp nào tôi nên xem xét một ngôn ngữ lập trình chức năng phù hợp hơn để thực hiện một nhiệm vụ nhất định? Bên cạnh vấn đề đa lõi phổ biến gần đây của lập trình song song.

Ý kiến ​​cá nhân của tôi là đa lõi không phải là tính năng sát thủ của FP (ít nhất là cho đến khi trình biên dịch Haskell, Scala, Clojure, F # giải quyết vấn đề cục bộ bộ đệm). Tính năng kẻ giết người là map, filter, foldvà bạn bè mà cho phép một biểu thức ngắn gọn hơn của một nhóm lớn các thuật toán. Điều này được kết hợp bởi các ngôn ngữ FP có cú pháp ngắn gọn hơn so với hầu hết các đối tác OO phổ biến.

Ngoài ra, việc gần gũi hơn với mô hình quan hệ giúp giảm sự không phù hợp trở kháng với RDBMS ... điều đó - một lần nữa - ít nhất là đối với những người không lập trình - rất hay.

Ngoài ra, khi bạn đặc biệt khó đáp ứng các yêu cầu 'chính xác' - ở dạng khó kiểm tra (phổ biến trong điện toán khoa học / phân tích dữ liệu lớn trong đó mục tiêu là nhận được trước đó và kết quả không thể xác định như vậy) FP có thể cung cấp lợi thế.

Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn cho là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt?

  • thiếu hỗ trợ công cụ (F # và một số Lisps là ngoại lệ, Scala đang trên đường)
  • khó hơn để vắt kiệt chút hiệu năng cuối cùng từ phần cứng của bạn
  • các cộng đồng thường tập trung vào các vấn đề khác nhau so với những vấn đề mà một nhóm lớn các dự án phát triển phần mềm thương mại phải đối mặt
  • rất ít nhà phát triển có kinh nghiệm trong việc sử dụng FP trong môi trường công nghiệp và nếu bạn có thể tìm thấy họ, bạn có thể phải cạnh tranh với mức lương và lợi ích mà ngành tài chính có thể mang lại
  • phong cách chức năng của lập trình có xu hướng khó gỡ lỗi hơn; tức là quan sát giữa các kết quả trong một chuỗi dài các hàm tổng hợp thường không thể thực hiện được trong hầu hết (tất cả?) trình gỡ lỗi

Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

  • Có bao nhiêu vấn đề của bạn có thể được giải quyết bằng cách thoát khỏi các thư viện / khung công tác trên nền tảng nào (ví dụ JVM hoặc .Net) có bao nhiêu vấn đề hoàn toàn mới? Có cấu trúc ngôn ngữ có khả năng thể hiện trực tiếp những vấn đề này không?

  • Bạn cần bao nhiêu kiểm soát mức độ thấp đối với hiệu suất không gian và thời gian của ứng dụng của bạn?

  • Làm thế nào nghiêm ngặt là yêu cầu "chính xác" của bạn?

  • Bạn có đủ khả năng để đào tạo lại các nhà phát triển và / hoặc cạnh tranh với những lợi ích được cung cấp bởi một số ngách có lợi nhuận cao trong phát triển SW không?


+1 @Alexander đây chắc chắn là một trong những câu trả lời hay nhất trong cuộc thảo luận này. Bạn đã mang đến một chiều hướng mới của các cuộc tranh luận bằng cách giới thiệu yếu tố con người, khó khăn trong việc tìm kiếm các nhà phát triển lành nghề và giữ cho họ có động lực. Tôi hoàn toàn đồng ý với tầm nhìn của bạn về các tính năng giết người của lang lang, bởi vì mỗi ngày tôi cũng thấy nhiều ngôn ngữ bắt buộc hơn khi áp dụng chúng. Nhưng bài đăng của bạn đã mở mắt tôi và nhận ra có nhiều điều tôi vẫn chưa biết về FP. Cuối cùng, quan điểm của bạn dựa trên nền tảng hiện có như .Net hoặc Java chắc chắn là rất hợp lệ và hoàn toàn hợp lý.
edalorzo

9

Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn cho là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt? (Bên cạnh thay đổi mô hình và khó đánh giá hiệu suất do đánh giá lười biếng).

Giả sử bạn là nhà phát triển C ++ / C # / Java trong ngành ...

Hãy chuẩn bị cho những đồng nghiệp gắt gỏng không muốn học bất cứ điều gì. Hãy chuẩn bị cho những ông chủ có mái tóc nhọn áp đặt những lựa chọn ngôn ngữ tồi "bởi vì họ đã từng là một lập trình viên". Hãy chuẩn bị cho các học giả quan trọng trên các diễn đàn bảo trợ bạn về đơn chất. Hãy chuẩn bị cho các cuộc chiến ngôn ngữ bất tận vì Scala thậm chí không có loại bỏ cuộc gọi đuôi và Clojure thực sự yêu cầu bàn đạp chân cho tất cả các dấu ngoặc và đừng bắt tôi bắt đầu trên Erlang.

Nếu bạn là một lập trình viên web thì cạm bẫy lớn nhất có lẽ sẽ là mái tóc của bạn.

Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

Tôi sẽ bắt đầu với nền tảng:

  • OCaml là tuyệt vời trên Linux và khủng khiếp trên Windows.
  • F # là tuyệt vời trên Windows và khủng khiếp trên Linux.
  • Scala và Clojure là tuyệt vời trên JVM.

1
Khi tôi đọc "Hãy chuẩn bị cho những đồng nghiệp cục cằn, những người không muốn học bất cứ điều gì." Tôi muốn hét lên: "Thật vậy! Thật quá!" nhưng nó thực sự buồn
Zelphir Kaltstahl

3

Đối với một quan điểm (thừa nhận thiên vị) về câu hỏi này, bạn có thể xem blog của Bob Harper, Loại Hiện sinh . Carnegie Mellon gần đây đã làm lại chương trình giảng dạy CS của họ để dạy lập trình chức năng trước tiên, với các mô hình khác chỉ được dạy một khi nền tảng vững chắc về lập trình chức năng đã được thiết lập, và Harper đang thổi phồng khi chương trình giảng dạy mới được triển khai trong thực tế .

Harper là một trong những nhà phát triển chính của ngôn ngữ lập trình Standard ML, vì vậy thật công bằng khi nói ý kiến ​​của riêng anh ấy về vấn đề này có thể được đoán trước, và anh ấy chắc chắn không ngại những tuyên bố gây tranh cãi khi tranh luận về vị trí này, nhưng anh ấy đưa ra trường hợp của anh ấy tốt


1
+1 Bài viết này chắc chắn rất thú vị và tôi sẽ giữ nó trong mục yêu thích của tôi kể từ bây giờ. Tôi nghĩ rằng dạy FP trước tiên chắc chắn là một cách tiếp cận tốt, bởi vì thực sự rất khó để thoát khỏi suy nghĩ cấp bách nếu bạn làm khác, và trên hết nếu bạn không sử dụng ngôn ngữ lập trình chức năng thuần túy thì rất khó để phá vỡ cái cũ thói quen. Tôi cũng thấy rằng các ngôn ngữ OOP chính đang kết hợp các tính năng chức năng và do đó có được các kỹ năng và trạng thái của một lập trình viên chức năng phải thực sự tiện dụng trong tương lai gần. Cái nhìn sâu sắc thú vị, cảm ơn!
edalorzo

@jimwise: +1 cho bài viết của Harper. Tôi thấy cách tiếp cận của anh ấy rất thích hợp. @edalorzo: Khi bạn bắt đầu suy nghĩ chức năng, bạn sẽ thấy mô hình bắt buộc như một biện pháp cuối cùng mà bạn phải áp dụng để tối ưu hóa chương trình của mình khi nó không đủ nhanh. Gần đây tôi đã viết một số công cụ nhỏ trong Scala, những công cụ không lớn nhưng không tầm thường và với một số chức năng thực sự. Thật ngạc nhiên, tôi đã không sử dụng varhoặc bất kỳ bộ sưu tập có thể thay đổi nào một lần. Vì vậy, suy nghĩ cấp thiết là IMO một số loại tối ưu hóa sớm mà như chúng ta đều biết, là gốc rễ của mọi tội lỗi.
Giorgio

2

Trong trường hợp nào tôi nên xem xét một ngôn ngữ lập trình chức năng phù hợp hơn để thực hiện một nhiệm vụ nhất định? Bên cạnh vấn đề đa lõi phổ biến gần đây của lập trình song song.

Không có công thức kỳ diệu nào cho bạn biết khi nào nên sử dụng lập trình chức năng. Nó không giống như lập trình hướng đối tượng phù hợp với các tình huống lập trình hiện tại của chúng tôi. Nó chỉ là một cách khác để cấu trúc các chương trình theo thuật ngữ khác.

Nếu tôi quyết định chuyển sang một ngôn ngữ lập trình chức năng mà bạn cho là những cạm bẫy lớn nhất mà tôi sẽ phải đối mặt? (Bên cạnh thay đổi mô hình và khó đánh giá hiệu suất do đánh giá lười biếng).

Lập trình chức năng không có gì để làm với sự lười biếng. ML và OCaml là các ngôn ngữ chức năng và nghiêm ngặt. Rào cản lớn nhất mà bạn sẽ phải đối mặt là cấu trúc mọi thứ theo các giá trị bất biến và quấn đầu xung quanh bất kỳ sự trừu tượng nào được sử dụng trong hệ thống loại cho các tác dụng phụ. Các ngôn ngữ chức năng phù hợp hơn để tối ưu hóa vì thực tế là chúng tạo ra các hiệu ứng phụ rất rõ ràng trong hệ thống loại. Haskell sử dụng các đơn nguyên nhưng có những cách tiếp cận khác để sử dụng hiệu ứng trong các ngôn ngữ chức năng thuần túy. Clean có các loại duy nhất và một số ngôn ngữ khác đang phát triển có những thứ khác.

Với rất nhiều ngôn ngữ lập trình chức năng ngoài kia, làm thế nào bạn chọn một ngôn ngữ phù hợp hơn với nhu cầu của bạn?

Trong số các ngôn ngữ lập trình tôi biết tôi chỉ nói Haskell và Clean có thể được gọi là ngôn ngữ chức năng. Tất cả những cái khác cho phép tác dụng phụ mà không làm cho những hiệu ứng đó rõ ràng trong hệ thống loại. Vì vậy, nếu bạn sẽ dành thời gian để học lập trình chức năng thì Haskell có lẽ là người duy nhất phù hợp với dự luật. Tất cả những cái khác mà tôi biết, Erlang, Scala, Clojure, v.v. chỉ cung cấp các khái niệm trừu tượng về chức năng trên một ngôn ngữ bắt buộc. Vì vậy, nếu bạn muốn tiếp cận mô hình chức năng theo bit thì tôi khuyên bạn nên Scala hoặc Erlang và nếu bạn muốn giải quyết mọi thứ ngay lập tức và có thể từ bỏ trong thất vọng thì bạn nên đi với Haskell.


@ Dadivk01 +1 Tôi thích lý do rằng lang lang chỉ là một công cụ cạnh tranh như bất kỳ công cụ nào khác và có thể được sử dụng để giải quyết các vấn đề tương tự như đã giải quyết với các mô hình khác. Tại sao bạn nghĩ rằng chúng ít phổ biến hơn, sau đó? Và, bạn có còn đồng ý rằng chúng phù hợp hơn để giải quyết vấn đề tính toán song song hơn so với hầu hết các lang OOP không? Bạn có nói rằng kiểu dữ liệu bất biến có ảnh hưởng đến dung lượng bộ nhớ và hiệu năng khi so sánh với các lang bắt buộc không? Tôi đã cho nó một cơ hội với Haskell, tại sao bạn lại nói "từ bỏ trong thất vọng", bạn đang làm tôi sợ, anh bạn :)
edalorzo

@edalorzo: Tôi không nghĩ lập trình chức năng là tốt hơn cho các thuật toán song song. Mọi người nhầm lẫn lập trình khai báo với lập trình chức năng. Những gì lập trình chức năng đã có cho nó là bản chất khai báo của nó và một nhóm người thực sự thông minh viết trình biên dịch xuất sắc để dịch mã khai báo sang mã máy. Bất kỳ ngôn ngữ nào khác thiên về mô tả các vấn đề thay vì đánh vần rõ ràng các chi tiết nhỏ sẽ tốt cho lập trình song song.
davidk01

@edalorzo: Đối với "từ bỏ trong thất vọng" Tôi nói rằng bởi vì nếu lập trình bắt buộc là tất cả những gì bạn biết thì hệ thống loại của haskell và cách tiếp cận đơn giản của nó để mô tả các hiệu ứng có thể hơi quá nhiều. Tôi nghĩ tốt hơn là bắt đầu với một ngôn ngữ có cách tiếp cận thực tế hơn đối với các tác dụng phụ như Erlang và Scala.
davidk01

0

Tôi cho rằng sự gia tăng hiện tại của các ngôn ngữ chức năng là thực tế rằng chúng là lý tưởng cho tính toán song song. Ví dụ, toàn bộ ý tưởng về giảm bản đồ dựa trên mô hình chức năng. Và không còn nghi ngờ gì nữa, tính toán song song sẽ tăng lên, vì rõ ràng việc mở rộng quy mô hiện nay dễ dàng hơn và rẻ hơn so với mở rộng quy mô. Ngay cả trên CPU thị trường tiêu dùng cũng nhận được nhiều lõi hơn, không nhiều GHz hơn.

EDIT: vì nó không rõ ràng cho tất cả.

Trong lập trình hàm thuần túy, một hàm lấy đầu vào, tạo đầu ra và không có tác dụng phụ. Không có tác dụng phụ, có nghĩa là nó không có trạng thái chia sẻ, do đó không cần cơ chế đồng bộ hóa, điều này sẽ cần thiết trong khi chạy đồng thời. Đồng bộ hóa là phần khó nhất trong mọi phần mềm đồng thời / song song, do đó thực hiện nó hoàn toàn là chức năng, về cơ bản bạn không phải đối phó với phần khó nhất.

Đối với bản đồ thu nhỏ, ngay cả tên cũng xuất phát từ lập trình chức năng (cả ánh xạ và thu nhỏ là các hoạt động điển hình trong mô hình chức năng). Cả hai bước của map-less là các hàm chạy song song, lấy đầu vào, tạo đầu ra và không có tác dụng phụ. Vì vậy, đây chính xác là ý tưởng lập trình chức năng thuần túy.

Một vài ví dụ về FP được sử dụng cho song song:

  • CouchDB - xây dựng trên Erlang
  • Trò chuyện trên Facebook - xây dựng trên Erlang
  • Twitter - xây dựng phần lớn trên Scala

3
Mọi người đều đưa ra yêu cầu lập trình song song nhưng có rất ít dữ liệu để sao lưu. Nếu bạn biết bất kỳ nguồn nào như vậy thì bạn nên trích dẫn chúng. Các tính toán phức tạp thường có các phụ thuộc dữ liệu phức tạp và nếu bạn sử dụng mô hình lập trình chức năng thì sự phụ thuộc dữ liệu vốn có của một số mô hình sẽ không biến mất một cách kỳ diệu. Lập trình GPU là song song như nó có được nhưng họ có được bằng cách sử dụng các ngôn ngữ bắt buộc chỉ tốt vì các mô hình họ làm việc có tích hợp song song.
davidk01

4
@vartec: Vì lợi ích của tính khách quan, nó vẫn sẽ tốt nếu bạn có thể cung cấp một tài liệu tham khảo để sao lưu các yêu cầu của bạn. Nó sẽ giúp những độc giả dốt nát hơn nhiều so với một câu hỏi ngược ...
blubb

1
@vartec: Thật ra là không, tôi chưa bao giờ nghĩ rằng có rất nhiều người đưa ra một số yêu cầu đã biến nó thành sự thật. Tôi đổ lỗi cho việc đào tạo toán học của mình, nhưng không phải tất cả chúng ta đều tin vào những thứ như sự thật phũ phàng và những lời biện minh cụ thể cho những tuyên bố của chúng tôi và bản chỉnh sửa của bạn vẫn không giải quyết nhận xét của tôi.
davidk01

1
@vartec Bạn có thể đặt một tham chiếu đến một nguồn đáng tin cậy ủng hộ các yêu cầu của bạn.
quant_dev

1
+1 @ davidk01 "Mọi người đều đưa ra yêu cầu lập trình song song nhưng có rất ít dữ liệu để sao lưu". Tôi nhận thức được một lượng lớn bằng chứng ngược lại. Ví dụ, các bài báo của Cilk mô tả mức độ đột biến tại chỗ là điều cần thiết nếu bạn muốn độ phức tạp của bộ đệm tốt, đây là một yêu cầu của khả năng song song có thể mở rộng trên đa lõi.
Jon Harrop
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.