Есть ли недостатки или проблемы с Haskell?

47

Я смотрю на погружение в Haskell для моего следующего (относительно тривиального) личного проекта. Причины, по которым я занимаюсь Haskell:

  1. Получить мою голову на чисто функциональный язык
  2. Скорость. Хотя я уверен, что с этим можно поспорить, из-за того, что я видел гвозди на Haskell, близкие к C ++ (и, похоже, немного быстрее, чем Erlang).
  3. Скорость. Веб-сервер Warp кажется сумасшедшим быстро по сравнению практически со всем остальным .

Итак, учитывая это, я ищу недостатки или проблемы, которые возникают вместе с Haskell. В Интернете огромное количество информации о том, почему Haskell - хорошая вещь, но я не нашел много тем о его уродливой стороне (кроме жалоб на его синтаксис, который меня совершенно не интересует).

Примером того, что я ищу, может быть как GIL Python. То, что не поднимало голову, пока я действительно не начал смотреть на использование параллелизма в среде CPython.

Демиан Брехт
источник
4
Нашел это на stackoverflow: stackoverflow.com/questions/1695076/pros-and-cons-of-haskell
FrustratedWithFormsDesigner
26
Я слышал, что меньшие программисты занимались вопросами таяния мозгов. Это очень дорогое заболевание.
ChaosPandion
1
@FrustratedWithFormsDesigner: спасибо за ссылку. Тем не менее, до сих пор нет никаких упоминаний о каких-либо технических недостатках в Haskell. Может быть, их нет ? ;)
Демиан Брехт
6
@ChaosPandion: я слышал то же самое. Но если вы не таете в мозгу, вы на самом деле пытаетесь ? ;) Кроме того, я бы на самом деле не считал себя программистом меньшего уровня, так что я не слишком обеспокоен этим;)
Демиан Брехт
3
@ChaosPandion: И большинство планов здравоохранения не покрывают это. :(
FrustratedWithFormsDesigner

Ответы:

48

Несколько минусов, о которых я могу думать:

  • Из-за природы языка и его твердых корней в академическом мире, сообщество очень математически; если вы прагматичный человек, иногда это может быть ошеломляющим, и если вы не говорите на жаргоне, вам будет сложнее, чем со многими другими языками.
  • В то время как существует огромное количество библиотек, документация часто краткая.
  • Хорошие учебники начального уровня немногочисленны и их трудно найти, поэтому начальная кривая обучения довольно крутая.
  • Некоторые языковые функции излишне неуклюжи; ярким примером является то, как синтаксис записи не вводит область именования, поэтому невозможно иметь одинаковое имя поля записи в двух разных типах в одном и том же пространстве имен модуля.
  • По умолчанию Haskell лениво оценивается, и, хотя это часто бывает здорово, иногда он может вас укусить. Наивное использование ленивых вычислений в нетривиальных ситуациях может привести к ненужным узким местам производительности, и понимание того, что происходит под капотом, не совсем просто.
  • Ленивая оценка (особенно в сочетании с чистотой и агрессивно оптимизирующим компилятором) также означает, что вы не можете легко определить порядок выполнения; на самом деле, вы даже не знаете, оценивается ли определенный фрагмент кода в данной ситуации. Следовательно, отладка кода на Haskell требует другого подхода, хотя бы потому, что пошаговое выполнение кода менее полезно и менее значимо.
  • Из-за чистоты Haskell вы не можете использовать побочные эффекты для таких вещей, как ввод / вывод; Вы должны использовать монаду и ленивую оценку «злоупотреблять» для достижения интерактивности, и вы должны перетаскивать монадический контекст куда угодно, где вы захотите выполнить ввод / вывод. (На самом деле это хорошая функция во многих отношениях, но иногда прагматичное кодирование невозможно).
tdammers
источник
16
На самом деле, сейчас есть несколько действительно хороших вводных книг, которые можно бесплатно скачать онлайн. Learn You a Haskell for Great Good - одна из лучших книг по программированию для начинающих, которые я когда-либо читал, и Real World Haskell - отличный промежуточный ресурс.
Тихон Джелвис
1
@TikhonJelvis: Это действительно единственные два кандидата, которых я нашел достойными; «Learn You A Haskell» смутил меня больше всего на свете, «Real World Haskell» работал для меня, но предполагает некоторый опыт программирования. Также есть «Нежное введение в Хаскелл», но оно очень нежное, особенно если вам не хватает знания по математике.
tdammers
Я использую "Нежное введение в Haskell" и "Real World Haskell". Сочетание этих двух дал мне много полезной информации. Я нахожусь на уровне, где я готов к нетривиальному проекту, но, к сожалению, у меня не так много времени для этого.
Джорджио
9
«если вы прагматичный человек ...»: иногда использование математически ориентированного языка может быть очень прагматичным решением, если в дальнейшем вам не придется много исправлять ошибки. Конечно, вы всегда должны находить баланс между тем, сколько времени вы экономите с помощью инструмента, и сколько дополнительного времени вам нужно, чтобы научиться его использовать.
Джорджио
Монады будут (и работают на других языках) работать точно так же на строгом языке. Вы абсолютно не «злоупотребляете» ленивыми оценками для достижения интерактивности, просто написать жесткую интерактивную программу на Haskell.
точка с запятой
19

Большинство недостатков Haskell (а также большинство преимуществ Haskell) обусловлены двумя его определяющими характеристиками: он ленивый и чисто функциональный.

Быть ленивым затрудняет рассуждения о производительности. Особенно для людей, не привыкших к лени, но даже для опытных пользователей Haskeller может быть трудно понять, как лень повлияет на производительность в определенных случаях.

Лень также означает, что труднее создавать точные тесты без использования таких библиотек, как Criterion.

Быть чисто функциональным означает, что всякий раз, когда вам нужно использовать изменяемые структуры данных (в тех случаях, когда невозможно добиться желаемой производительности без них - хотя благодаря оптимизатору GHC, который происходит не так часто, как вы думаете), вы будете застрял в монаде IO (или ST), что делает код более громоздким.

Поскольку вы упомянули скорость в качестве одной из своих целей, я должен отметить, что зачастую между производительностью, оптимизированной вручную, и кодом на Haskell, написанном без особого внимания к производительности (в большей степени, чем в других языках), часто бывают огромные различия в производительности. И оптимизированный вручную код на Haskell часто бывает довольно уродливым (хотя я полагаю, что это также верно для большинства других языков).

sepp2k
источник
1
Чисто функциональный на самом деле является функцией продажи, а не недостатком. Язык «ленивый» не имеет смысла, ленивый против строгого - это вопрос типов, и у ленивых и строгих типов есть свое применение. (Таким образом, Haskell так же ограничен отсутствием строгих типов, как большинство языков ограничено отсутствием ленивых типов.) Основными недостатками Haskell являются его дрянная система модулей (модули не первоклассные), а классы фактических типов фактически нарушают модульность ( Правило «один экземпляр на тип» заставляет компилятор вести глобальный список экземпляров класса типа).
Pyon
21
«И оптимизированный вручную код на Haskell часто бывает довольно уродливым (хотя я полагаю, что это также верно для большинства других языков)». Этот. Когда люди хотят продемонстрировать элегантность Haskell, они публикуют короткий и приятный код, который, к сожалению, даст вам довольно низкую производительность, если он будет работать с производственным объемом данных. Когда люди хотят показать, что «Haskell так же быстр, как C ++», они публикуют извилистый и трудно читаемый код, который все еще медленнее, чем гораздо более читаемая версия на C.
quant_dev
12

Я не эксперт по Haskell: я изучил основы, но, к сожалению, у меня не было возможности сделать какой-то серьезный проект на Haskell (хотя мне бы хотелось, потому что мне этот язык очень нравится).

Однако из того, что я знаю, и из обсуждения с кем-то, кто работал в области, достаточно близкой к функциональному программированию, Haskell может быть не лучшим решением, когда вы хотите реализовать алгоритмы графов, где вам нужно, например, пройтись по графу и выполнить много локальных изменений в структуре графа.

Поскольку граф в целом не имеет рекурсивной структуры, я считаю, что наилучшим подходом является создание одной копии графа с использованием структур и указателей между ними (как вы можете это сделать, например, в C ++) и манипулирование этой копией путем изменения указателей, создание или уничтожение узлов и так далее.

Мне интересно, как такие структуры данных и операции могут обрабатываться должным образом в Haskell, поскольку, насколько я знаю в Haskell, невозможно использовать вышеуказанное представление / подход. Некоторые проблемы с алгоритмами на графах в Haskell кратко обсуждаются в этой статье

РЕДАКТИРОВАТЬ

Недавно я говорил с экспертом по функциональному программированию, и он подтвердил, что эффективная реализация определенного алгоритма графов может быть довольно сложной в Haskell: перемещение по указателям, как вы делаете в C или C ++, может быть намного быстрее.

Джорджио
источник
Интересные заметки (и ссылки) на манипуляции / обходе графа в чисто функциональном мире. Не учел это.
Демиан Брехт
7
Чисто функциональные графовые алгоритмы - интересная тема. Идиоматическое решение состоит в том, чтобы эмулировать императивное представление, заменяя указатели чисто функциональными словарями, например, отображая данную вершину на множество вершин, к которым у нее есть ребра. Однако, если не использовать слабый словарь, это приведет к утечке памяти, потому что недоступные подграфы не могут быть собраны, и нет известного чисто функционального слабого словаря. В конце концов, современное чисто функциональное решение является одновременно гораздо более сложным и гораздо менее эффективным!
Джон Харроп
1
С другой стороны, алгоритмы графов могут быть чрезвычайно сложными для отладки, а постоянная структура данных может облегчить эту проблему ...
Джон Харроп
Мне было интересно, можно ли будет разработать тип данных графа (следуя идее ByteString: эффективное внутреннее представление плюс функции преобразования / доступа). Используя монады, можно сделать такие графики изменяемыми. Конечно, это решит проблему представления графов, но не реализацию алгоритмов графов.
Джорджио
DAG - это одно. Для всего остального можно воспользоваться ленью и «завязать узел».
Даниэль
4

Недостатком Haskell является то, что он другой. Это больший шаг по сравнению с языками, которые чаще всего преподаются или о которых говорят, поэтому будет большая кривая обучения. Это также менее популярный язык, который может ограничить доступ к справке, если вы застряли. Это действительно не главные недостатки, хотя.

Единственным недостатком является то, что это функциональный язык, поэтому он менее полезен для определенных проблемных областей, но это верно и для объектно-ориентированных языков. Как правило, языки не имеют истинных недостатков за пределами обучения, по крайней мере, для относительно популярных языков. Пока язык завершен по Тьюрингу, он теоретически способен на все.

Ryathal
источник
3
Тьюринговая полнота - это красная сельдь. Теория вычислений! = Практическое программирование.
1
@delnan, вот почему я сказал теоретически
Ryathal
2
Что это за «проблемные домены», для которых Haskell предположительно менее полезен?
Андрес Ф.
3
Хотя это правда, что сообщество меньше , на самом деле оно непропорционально активно. Я думаю, что канал #haskell на freenode отстает только от популярности #python среди языковых каналов, и ответы на вопросы о Haskell на SO удивительно конкурентоспособны :)
Тихон Джелвис
@AndresF. - Я бы не сказал, что «менее полезен», но вот некоторые области, в которых Haskell определенно все еще находится в зачаточном состоянии: 1) тяжелый DP - я написал простой алгоритм ранца и был буквально шокирован тем, как медленно это было. При этом использовались массивы в штучной упаковке, поэтому я ожидал некоторых накладных расходов, но это было намного хуже, чем я ожидал. 2) большие нетривиальные игры - AFRP находится в зачаточном состоянии, поэтому нет особенно хороших фреймворков, а производительность все еще слишком сложно прогнозировать. Пройдет много времени, прежде чем мы увидим версию Doom на Haskell. (фрагмент не считается - у него нет ИИ.)
rtperson
0

Итак, учитывая это, я ищу недостатки или проблемы, которые возникают вместе с Haskell

«Проблемы с Haskell», как правило, появляются в определенных областях. Haskell - замечательный язык для разработки приложений, гораздо приятнее писать, чем что-либо еще. Проблемы, как правило, возникают, когда вы пытаетесь сделать что-то, для чего нет хорошей поддержки, например:

  • Кросс-компиляция. GHC может быть построен как кросс-компилятор, но процесс довольно сложный.
  • Встроенные приложения. У Haskell есть управление памятью через сборщик мусора, так что это не слишком удивительно.
  • Скорость. Haskell не так быстр, как Rust, хотя в большинстве случаев он будет конкурировать довольно хорошо. Это сильно зависит от предметной области - чистые вычисления хорошо оптимизируются, но что-то вроде «чтения файла в буфер и подсчета количества строк» ​​сложнее выразить в Haskell.

источник