Có bất kỳ nhược điểm hoặc vấn đề với Haskell?


47

Tôi đang xem xét lặn vào Haskell cho dự án cá nhân tiếp theo (tương đối tầm thường) của tôi. Những lý do mà tôi giải quyết Haskell là:

  1. Đưa đầu tôi vào một ngôn ngữ hoàn toàn chức năng
  2. Tốc độ. Mặc dù tôi chắc chắn rằng điều này có thể được tranh luận, hồ sơ rằng tôi đã thấy móng tay Haskell gần với C ++ (và dường như nhanh hơn một chút so với Erlang).
  3. Tốc độ. Máy chủ web Warp dường như phát điên nhanh so với hầu hết mọi thứ khác .

Vì vậy, với điều này, những gì tôi đang tìm kiếm là những nhược điểm hoặc vấn đề đi kèm với Haskell. Web có một lượng thông tin khổng lồ về lý do tại sao Haskell là một điều tốt, nhưng tôi không tìm thấy nhiều chủ đề về mặt xấu của nó (ngoài những hiểu biết về cú pháp mà tôi không quan tâm chút nào).

Một ví dụ về những gì tôi đang tìm kiếm có thể giống như GIL của Python. Một cái gì đó không ngẩng cao đầu cho đến khi tôi thực sự bắt đầu xem xét sử dụng đồng thời trong môi trường CPython.



26
Tôi đã nghe nói các lập trình viên ít hơn đã xử lý các vấn đề tan chảy não. Đó là một điều kiện rất tốn kém để điều trị.
ChaosPandion

1
@FrustratedWithFormsDesigner: Cảm ơn vì liên kết. Tuy nhiên, vẫn không có bất kỳ tài liệu tham khảo nào về bất kỳ nhược điểm kỹ thuật nào đối với Haskell .. Liệu nó có tồn tại không ? ;)
Demian Brecht

6
@ChaosPandion: Tôi cũng đã nghe như vậy .. Nhưng nếu bạn không làm tan chảy bộ não của mình, bạn có thực sự đang cố gắng không? ;) Ngoài ra, tôi sẽ không thực sự coi mình là một lập trình viên ít hơn, vì vậy tôi không quá quan tâm đến điều đó;)
Demian Brecht

3
@ChaosPandion: Và hầu hết các chương trình sức khỏe không bao gồm nó. :(
Thất vọngWithFormsDesigner

Câu trả lời:


48

Một vài nhược điểm tôi có thể nghĩ đến:

  • Do bản chất của ngôn ngữ và nguồn gốc vững chắc của nó trong thế giới học thuật, cộng đồng rất có đầu óc toán học; nếu bạn là một người thực dụng, đôi khi điều này có thể trở nên quá sức và nếu bạn không nói biệt ngữ, bạn sẽ có một thời gian khó khăn hơn so với nhiều ngôn ngữ khác.
  • Mặc dù có rất nhiều thư viện đáng kinh ngạc, tài liệu thường rất ngắn gọn.
  • Hướng dẫn cấp độ nhẹ nhàng rất ít và khó tìm, vì vậy đường cong học tập ban đầu khá dốc.
  • Một vài tính năng ngôn ngữ là vụng về không cần thiết; một ví dụ nổi bật là cách cú pháp bản ghi không giới thiệu phạm vi đặt tên, vì vậy không có cách nào để có cùng tên trường bản ghi trong hai loại khác nhau trong cùng một không gian tên mô-đun.
  • Haskell mặc định để đánh giá lười biếng, và trong khi điều này thường là một điều tuyệt vời, đôi khi nó có thể cắn bạn theo những cách khó chịu. Sử dụng đánh giá lười biếng một cách ngây thơ trong các tình huống không tầm thường có thể dẫn đến các tắc nghẽn hiệu suất không cần thiết và việc hiểu những gì đang diễn ra dưới mui xe không thực sự đơn giản.
  • Đánh giá lười biếng (đặc biệt là kết hợp với độ tinh khiết và trình biên dịch tối ưu hóa mạnh mẽ) cũng có nghĩa là bạn không thể dễ dàng suy luận về thứ tự thực hiện; thực tế, bạn thậm chí không biết liệu một đoạn mã nhất định có thực sự được đánh giá trong một tình huống nhất định hay không. Do đó, việc gỡ lỗi mã Haskell đòi hỏi một tư duy khác, nếu chỉ vì bước qua mã của bạn ít hữu ích hơn và ít ý nghĩa hơn.
  • Vì độ tinh khiết của Haskell, bạn không thể sử dụng các tác dụng phụ để làm những việc như I / O; bạn phải sử dụng đánh giá lười biếng đơn lẻ và 'lạm dụng' để đạt được tính tương tác và bạn phải kéo bối cảnh đơn điệu xung quanh bất cứ nơi nào bạn có thể muốn thực hiện I / O. (Đây thực sự là một tính năng tốt theo nhiều cách, nhưng đôi khi nó không thể mã hóa thực tế.)

16
Thực sự có một số sách giới thiệu thực sự tốt có sẵn miễn phí trực tuyến. Learn You a Haskell for Great Good là một trong những cuốn sách lập trình dành cho người mới bắt đầu tốt nhất tôi từng đọc và Real World Haskell là một tài nguyên trung gian tuyệt vời.
Tikhon Jelvis

1
@TikhonJelvis: Đó thực sự là hai ứng cử viên duy nhất tôi thấy đáng để sử dụng; "Learn You A Haskell" làm tôi bối rối hơn bất cứ điều gì, "Real World Haskell" làm việc cho tôi nhưng giả định một chút về nền tảng lập trình. Ngoài ra còn có "Giới thiệu nhẹ nhàng về Haskell", nhưng tất cả đều nhẹ nhàng, đặc biệt nếu bạn thiếu nền tảng về Toán học.
tdammers

Tôi sử dụng "Giới thiệu nhẹ nhàng về Haskell" và "Real World Haskell". Sự kết hợp của cả hai đã cho tôi rất nhiều thông tin hữu ích. Tôi đang ở một mức độ mà tôi đã sẵn sàng cho một dự án không tầm thường nhưng tiếc là tôi không có nhiều thời gian cho nó.
Giorgio

9
"Nếu bạn là một người thực dụng ...": đôi khi sử dụng ngôn ngữ định hướng toán học có thể là một quyết định rất thực tế nếu điều đó tránh cho bạn rất nhiều sửa lỗi sau này. Tất nhiên, bạn phải luôn tìm thấy sự cân bằng giữa thời gian bạn tiết kiệm được bằng cách sử dụng một công cụ và bạn cần bao nhiêu thời gian để học cách sử dụng nó.
Giorgio

Monads sẽ (và làm trong các ngôn ngữ khác) hoạt động chính xác trong một ngôn ngữ nghiêm ngặt. Bạn tuyệt đối không "lạm dụng" đánh giá lười biếng để đạt được tính tương tác, việc viết một chương trình tương tác nghiêm ngặt trong Haskell là chuyện nhỏ.
dấu chấm phẩy

19

Hầu hết các nhược điểm của Haskell (cũng như hầu hết các nhược điểm của Haskell) đến từ hai đặc điểm xác định của nó: Đó là sự lười biếng và hoàn toàn hoạt động.

Lười biếng làm cho khó khăn hơn để lý do về hiệu suất. Đặc biệt đối với những người không quen với sự lười biếng, nhưng ngay cả đối với những người Haskeller có kinh nghiệm cũng khó có thể thấy sự lười biếng sẽ ảnh hưởng đến hiệu suất trong một số trường hợp nhất định.

Lười biếng cũng có nghĩa là khó tạo ra điểm chuẩn chính xác mà không sử dụng các thư viện như Tiêu chí.

Hoàn toàn là chức năng có nghĩa là bất cứ khi nào bạn cần sử dụng các cấu trúc dữ liệu có thể thay đổi (trong trường hợp không thể đạt được hiệu suất mong muốn mà không có chúng - mặc dù nhờ trình tối ưu hóa của GHC không xảy ra thường xuyên như bạn nghĩ), bạn sẽ bị mắc kẹt trong đơn vị IO (hoặc ST), làm cho mã trở nên cồng kềnh hơn.

Vì bạn đã đề cập đến tốc độ là một trong những mục tiêu của mình, tôi nên chỉ ra rằng thường có sự khác biệt lớn về hiệu suất giữa mã Haskell được tối ưu hóa bằng tay và mã Haskell được viết mà không cần suy nghĩ nhiều về hiệu suất (hơn cả các ngôn ngữ khác). Và mã Haskell được tối ưu hóa bằng tay thường khá xấu (mặc dù tôi cho rằng điều đó cũng đúng trong hầu hết các ngôn ngữ khác).


1
Hoàn toàn chức năng thực sự là một tính năng bán hàng, không phải là một nhược điểm. Một ngôn ngữ "lười biếng" không có ý nghĩa, lười biếng và nghiêm khắc là vấn đề của các loại và cả loại lười biếng và nghiêm ngặt đều có cách sử dụng. (Vì vậy, Haskell cũng bị tê liệt do không có các loại nghiêm ngặt vì hầu hết các ngôn ngữ đều bị tê liệt do không có các loại lười biếng.) Nhược điểm chính của Haskell là hệ thống mô-đun điên rồ của nó (các mô-đun không phải là hạng nhất) và các lớp loại thực tế phá vỡ tính mô đun ( Quy tắc "một thể hiện cho mỗi loại" buộc trình biên dịch giữ một danh sách toàn cầu về các thể hiện của lớp loại).
pyon

21
"Và mã Haskell được tối ưu hóa bằng tay thường khá xấu (mặc dù tôi cho rằng điều đó cũng đúng trong hầu hết các ngôn ngữ khác)." Điều này. Khi mọi người muốn thể hiện sự thanh lịch của Haskell, họ xuất bản mã ngắn và ngọt, điều không may sẽ mang lại cho bạn hiệu suất khá tệ nếu chạy trên một lượng dữ liệu giống như sản xuất. Khi mọi người muốn chứng minh rằng "Haskell nhanh như C ++", họ xuất bản mã phức tạp và khó đọc, tốc độ này vẫn chậm hơn phiên bản dễ đọc hơn nhiều trong C.
quant_dev

12

Tôi không phải là chuyên gia của Haskell: Tôi đã học được những điều cơ bản nhưng tiếc là tôi chưa có cơ hội thực hiện một dự án nghiêm túc nào đó ở Haskell (mặc dù tôi rất thích, vì tôi thích ngôn ngữ này rất nhiều).

Tuy nhiên, từ những gì tôi biết và từ một cuộc thảo luận với ai đó đang làm việc trong một lĩnh vực khá gần với lập trình chức năng, Haskell có thể không phải là giải pháp tốt nhất khi bạn muốn thực hiện các thuật toán đồ thị, nơi bạn cần ví dụ để đi qua biểu đồ và thực hiện nhiều thay đổi cục bộ trên cấu trúc đồ thị.

Do biểu đồ nói chung không có cấu trúc đệ quy, cảm giác của tôi là cách tiếp cận tốt nhất là xây dựng một bản sao của biểu đồ bằng cách sử dụng các cấu trúc và con trỏ giữa chúng (như bạn có thể làm như trong C ++) và điều khiển bản sao đó bằng cách thay đổi con trỏ, tạo hoặc phá hủy các nút, v.v.

Tôi tự hỏi làm thế nào các cấu trúc dữ liệu và hoạt động như vậy có thể được xử lý đúng cách trong Haskell, vì theo hiểu biết của tôi về Haskell, không thể sử dụng cách biểu diễn / cách tiếp cận ở trên. Một số vấn đề với thuật toán đồ thị trong Haskell được thảo luận ngắn gọn trong bài viết này

BIÊN TẬP

Gần đây tôi đã nói chuyện với một chuyên gia về lập trình chức năng và anh ấy đã xác nhận rằng việc triển khai một số thuật toán đồ thị hiệu quả có thể khá khó khăn trong Haskell: di chuyển xung quanh các con trỏ như bạn làm trong C hoặc C ++ có thể nhanh hơn nhiều.


Ghi chú thú vị (và liên kết) về thao tác / duyệt đồ thị trong một thế giới chức năng thuần túy. Chưa xem xét điều đó.
Demian Brecht

7
Các thuật toán đồ thị hoàn toàn chức năng là một chủ đề thú vị. Giải pháp thành ngữ là mô phỏng biểu diễn mệnh lệnh bằng cách thay thế các con trỏ bằng các từ điển chức năng thuần túy, ví dụ ánh xạ một đỉnh đã cho vào tập các đỉnh mà nó có các cạnh. Tuy nhiên, trừ khi sử dụng từ điển yếu, điều này sẽ làm rò rỉ bộ nhớ vì các sơ đồ con không thể truy cập không thể được thu thập và không có từ điển yếu chức năng đơn thuần nào được biết đến. Vào cuối ngày, một giải pháp hoàn toàn chức năng hiện đại vừa phức tạp hơn vừa kém hiệu quả hơn nhiều!
Jon Harrop

1
Mặt khác, các thuật toán đồ thị có thể rất khó gỡ lỗi và cấu trúc dữ liệu liên tục có thể làm giảm bớt vấn đề này ...
Jon Harrop

Tôi đã tự hỏi nếu có thể phát triển một loại dữ liệu đồ thị (theo ý tưởng của ByteString: biểu diễn nội bộ hiệu quả cộng với các chức năng chuyển đổi / truy cập). Sử dụng các đơn vị nên có thể làm cho các biểu đồ như vậy có thể thay đổi. Tất nhiên điều này sẽ giải quyết vấn đề đại diện cho đồ thị nhưng không phải là việc thực hiện các thuật toán đồ thị.
Giorgio

DAG là một chuyện. Đối với mọi thứ khác, bạn có thể khai thác sự lười biếng và "thắt nút".
danielm

4

Mặt trái của Haskell là nó khác biệt. Đó là một bước tiến lớn hơn so với các ngôn ngữ thường được dạy hoặc nói nhiều hơn, vì vậy sẽ có một đường cong học tập lớn hơn. Nó cũng ít phổ biến hơn về ngôn ngữ có thể hạn chế khả năng trợ giúp nếu bạn gặp khó khăn. Đây thực sự không phải là nhược điểm lớn.

Một điều có một nhược điểm tiềm năng là nó là ngôn ngữ chức năng, vì vậy nó ít hữu ích hơn đối với các miền có vấn đề nhất định, nhưng điều này cũng đúng với các ngôn ngữ hướng đối tượng. Nói chung, các ngôn ngữ không có tiêu cực thực sự ngoài các đường cong học tập, ít nhất là đối với các ngôn ngữ tương đối phổ biến. Miễn là một ngôn ngữ là Turing hoàn chỉnh, về mặt lý thuyết nó có khả năng cho bất cứ điều gì.


3
Turing hoàn chỉnh là một cá trích đỏ. Lý thuyết tính toán! = Lập trình thực tế.

1
@delnan đó là lý do tại sao tôi nói về mặt lý thuyết
Ryathal

2
Những "miền vấn đề" mà Haskell được cho là ít hữu ích hơn là gì?
Andres F.

3
Mặc dù đúng là cộng đồng nhỏ hơn , nhưng nó thực sự hoạt động không tương xứng. Tôi nghĩ rằng kênh #haskell trên freenode chỉ đứng sau #python về mức độ phổ biến trong các kênh ngôn ngữ và việc trả lời các câu hỏi về Haskell trên SO là cạnh tranh đáng ngạc nhiên :)
Tikhon Jelvis

@AresresF. - Tôi sẽ không đi xa để nói "ít hữu ích hơn", nhưng đây là một số lĩnh vực mà Haskell chắc chắn vẫn còn thể hiện ở giai đoạn sơ khai: 1) DP nặng - Tôi đã mã hóa một thuật toán ba lô đơn giản, và thực sự bị sốc về cách chậm rồi Đó là sử dụng các mảng được đóng hộp, vì vậy tôi mong đợi một số chi phí, nhưng nó tệ hơn nhiều so với tôi dự đoán. 2) các trò chơi không tầm thường lớn - AFRP đang ở giai đoạn đầu, do đó không có khung đặc biệt tốt và hiệu suất vẫn còn quá khó để dự đoán. Sẽ còn rất lâu nữa chúng ta mới thấy phiên bản Haskell của Doom. (không tính - nó không có AI.)
rtperson

0

Vì vậy, với điều này, những gì tôi đang tìm kiếm là những nhược điểm hoặc vấn đề đi kèm với Haskell

"Các vấn đề với Haskell" có xu hướng xuất hiện trong một số miền nhất định. Haskell là một ngôn ngữ tuyệt vời để lập trình ứng dụng, dễ viết hơn nhiều so với bất kỳ thứ gì khác. Các vấn đề có xu hướng tăng lên khi bạn cố gắng làm điều gì đó không hỗ trợ tốt, chẳng hạn như:

  • Biên dịch chéo. GHC có thể được xây dựng như một trình biên dịch chéo, nhưng quá trình này khá liên quan.
  • Ứng dụng nhúng. Haskell có quản lý bộ nhớ thông qua bộ thu gom rác, vì vậy điều này không quá ngạc nhiên.
  • Tốc độ. Haskell không nhanh như Rust, mặc dù trong hầu hết các trường hợp, nó sẽ cạnh tranh khá tốt. Nó phụ thuộc rất nhiều vào miền ứng dụng - các tính toán thuần túy được tối ưu hóa tốt, nhưng một cái gì đó như "đọc tệp vào bộ đệm và đếm số dòng" khó diễn đạt hơn trong Haskell.
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.