Какой язык учить после Haskell? [закрыто]

85

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

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

  • Система сильных типов. Одна из моих любимых частей программирования на Haskell - это написание объявлений типов. Это помогает структурировать мои мысли об отдельных функциях и их отношении к программе в целом. Это также упрощает неформальные рассуждения о правильности моей программы. Меня волнует правильность, а не эффективность.
  • Упор на рекурсию, а не на итерацию. Я использую итеративные конструкции в Haskell, но реализую их рекурсивно. Однако гораздо легче понять структуру рекурсивной функции, чем сложную итеративную процедуру, особенно при использовании комбинаторов и функций высшего порядка, таких как карты, складки и связывание.
  • Полезно учиться. Haskell - полезный язык для работы. Это немного похоже на чтение Канта. Однако у меня несколько лет назад этого не было. Я не ищу C. Язык должен обеспечивать концептуально интересную парадигму, чего, по моему полностью субъективному мнению, C-like не делают.

Взвешивание ответов : это, конечно, всего лишь заметки. Я просто хочу ответить всем, кто дал правильные ответы. Вы мне очень помогли.

1) В нескольких ответах указано, что сильный статически типизированный язык с акцентом на рекурсию означает другой функциональный язык. Хотя я хочу и дальше активно работать с Haskell, camccann и larsmans правильно отметили, что другой такой язык «слишком облегчит переход». Эти комментарии были очень полезны, потому что я не собираюсь писать Haskell на Caml! Из помощников по доказательству интересно выглядят Coq и Agda. В частности, Coq предоставит основательное введение в конструктивную логику и формальную теорию типов. Я потратил немного времени на предикаты первого порядка и модальную логику (Mendellsohn, Enderton, некоторые из Hinman), так что, вероятно, мне бы очень понравилось работать с Coq.

2) Другие сильно отдали предпочтение Lisp (Common Lisp, Scheme и Clojure). Из того, что я понимаю, как Common Lisp и Scheme имеют отличный вводный материал ( On Lisp и мотивированный Schemer , SICP ). Материал в SICP заставляет меня склоняться к Scheme. В частности, Scheme через SICP будет охватывать другую стратегию оценки, реализацию лени и возможность сосредоточиться на таких темах, как продолжения, интерпретаторы, символьные вычисления и т. Д. Наконец, как отмечали другие, обработка кода / данных в Lisp была бы совершенно новой. Следовательно, я сильно склоняюсь к варианту (2), Lisp.

3) В-третьих, Пролог. В Prolog есть масса интересного материала, и его основная область как раз то, что мне интересно. У него простой синтаксис, и его легко читать. На данный момент я не могу комментировать больше, но после прочтения обзора Prolog и беглого просмотра некоторых вводных материалов он занимает место (2). И кажется, что возврат Пролога всегда взламывается в Haskell!

4) Из основных языков наиболее интересным выглядит Python. Тим Йейтс заставляет языки звучать очень привлекательно. Судя по всему, Python часто преподают на первых курсах специализации CS; так что он либо концептуально богат, либо его легко освоить. Придется провести дополнительные исследования.

Всем спасибо за рекомендации! Похоже, что основными рекомендуемыми языками являются Lisp (Scheme, Clojure), Prolog или помощник по проверке, такой как Coq или Agda.

данпортин
источник
34
2,5 месяца - недостаточно, чтобы выучить какой-либо язык углубленно, извините, что лопнул ваш пузырь.
Woot4Moo,
20
Это, конечно, правда. Я не имел в виду, что «изучил» Haskell, что бы это ни значило. Я имел в виду, что мне комфортно пользоваться языком. Я явно не перестану этому учиться.
danportin
10
@Michael: Кодирование для правильности, а не эффективности - это то, что я хотел бы видеть больше ...
Дениз Доган
24
@ Woot4Moo: 2,5 месяца - это достаточно времени, чтобы «освоиться» с языком. Вдвойне, если он знаком с формальной логикой и работает с абстрактными концепциями из своего философского опыта. В этом случае также поможет отсутствие необходимости отучаться от других языков.
CA McCann,
8
@gnovice: Об этом, конечно же, много раз спрашивали. Но я впервые сталкиваюсь с кем-то, кто получил свой первый серьезный опыт программирования на Haskell. Это как если бы стрела времени перевернулась или что-то в этом роде.
Мухаммад Алькарури,

Ответы:

85

Я хотел бы расширить свои познания в программировании. (...) Я подумал, что задам вопрос здесь вместе с несколькими оговорками о типе языка, который я ищу. Некоторые из них субъективны, некоторые предназначены для облегчения перехода с Haskell.

Система сильных типов. (...) Это также упрощает неформальные рассуждения о правильности моей программы. Меня волнует правильность, а не эффективность.

Упор на рекурсию, а не на итерацию. (...)

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

  • Не обращайте внимания на практичность и идите на «больше Haskell, чем Haskell» : система типов Haskell полна дыр из-за отсутствия завершения и других беспорядочных компромиссов. Уберите беспорядок и добавьте более мощные функции, и вы получите такие языки, как Coq и Agda , где тип функции содержит доказательство ее правильности (вы даже можете прочитать стрелку функции ->как логическое следствие!). Эти языки использовались для математических доказательств и для программ с чрезвычайно высокими требованиями к корректности. Coq, вероятно, является наиболее заметным языком этого стиля, но Agda больше похожа на Haskell (а также написана на самом Haskell).

  • Не обращайте внимания на типы, добавьте больше магии : если Haskell - это волшебство, Lisp - это грубая, изначальная магия творения. Языки семейства Lisp (включая Scheme и Clojure ) обладают почти беспрецедентной гибкостью в сочетании с крайним минимализмом. В языках практически отсутствует синтаксис, код написан непосредственно в виде древовидной структуры данных; метапрограммирование на Лиспе проще, чем немета-программирование на некоторых языках.

  • Компромисс немного и двигаться ближе к мейнстриму : Haskell попадает в широкую семью языков влияние в большой степени ML, любой из которых вы могли бы , вероятно , смещаются к не слишком много трудностей. Haskell - один из самых строгих, когда дело доходит до гарантий правильности типов и использования функционального стиля, тогда как другие часто являются либо гибридными стилями, либо идут на прагматические компромиссы по разным причинам. Если вам нужен доступ к ООП и доступ к множеству основных технологических платформ, либо Scala на JVM, либо F #на .NET имеют много общего с Haskell, обеспечивая легкую совместимость с платформами Java и .NET. F # поддерживается непосредственно Microsoft, но имеет некоторые досадные ограничения по сравнению с Haskell и проблемы переносимости на платформах, отличных от Windows. Scala имеет прямые аналоги большей части системы типов Haskell и кроссплатформенный потенциал Java, но имеет более тяжеловесный синтаксис и не имеет мощной сторонней поддержки, которой обладает F #.

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

CA McCann
источник
4
I семейства Coq и Agda вы также можете посмотреть на Qi II .
Hynek -Pichi- Vychodil
Какими, на ваш взгляд, были бы досадные ограничения F #? Мне любопытно узнать, кто изучает F # в свободное время.
Лукас,
7
@Lucas: Главное против простого Haskell - это отсутствие высокодородного полиморфизма и классов типов. Кроме того, довольно много расширений, специфичных для GHC . Это ни в коем случае не является фатальным недостатком, но после того, как я привык к Haskell, без этого становится немного неуклюже. Представьте, что вы возвращаетесь от современного C # к использованию C # 1.x ...
CA McCann,
@HyneK: Этот язык Qi 2 на первый взгляд кажется очень интересным и более гибким, чем Coq или Adga. Похоже, автор решил прекратить работу. Есть ли движение к продолжению работы над этим языком? Я бы не хотел изучать то, что уже наполовину мертво.
Alex
@Alex: похоже, это продолжается под именем Шена: shenlanguage.org
amindfv
20

Я буду этим парнем и предположу, что вы просите не то.

Сначала вы говорите, что хотите расширить свой кругозор. Затем вы описываете язык, который вам нужен, и его горизонты невероятно похожи на те, которые у вас уже есть. Вы не добьетесь многого, изучая одно и то же снова и снова.

Я бы посоветовал вам изучить Lisp, то есть Common Lisp, Scheme / Racket или Clojure. Все они по умолчанию динамически типизированы, но имеют своего рода подсказку типа или дополнительную статическую типизацию. Racket и Clojure, вероятно, ваши лучшие ставки.

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

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

Макросистемы в Лиспе очень интересны и намного мощнее всего, что вы увидите где-либо еще. Одно это стоит хотя бы взглянуть.

Чак
источник
3
Хех, с точки зрения Haskell, подсказки типов или необязательная статическая типизация на самом деле не сильно отличаются от полностью динамической типизации. Это совсем другое мышление. Тем не менее, языки Lisp-y доставляют удовольствие, и я думаю, что каждый программист должен потратить хотя бы некоторое время на изучение.
CA McCann,
19

С точки зрения того, что подходит вашей специальности, очевидным выбором будет логический язык, такой как Prolog или его производные. Логическое программирование может быть выполнено очень аккуратно на функциональном языке (см., Например, The Reasoned Schemer ), но вам может понравиться работать напрямую с логической парадигмой.

Интерактивная система доказательства теорем, такая как twelf или coq, также может поразить ваше воображение.

sclv
источник
2
Поскольку вы заявляете о своем интересе к строго типизированному языку, я бы порекомендовал lambdaProlog, типизированный язык логического программирования более высокого порядка. Одна скомпилированная реализация - это Teyjus - code.google.com/p/teyjus (раскрытие: я работал над Teyjus).
Зак Сноу
18

Я бы посоветовал вам изучить Coq , мощный помощник по доказательству с синтаксисом, который будет удобен программисту на Haskell. Самое интересное в Coq - это то, что его можно извлечь на другие функциональные языки, включая Haskell. Существует даже пакет ( Meldable-Heap ) на Hackage, который был написан на Coq, свойства его работы были проверены, а затем извлечены в Haskell.

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

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

Томас М. ДюБюиссон
источник
1
Agda звучит как естественный "следующий шаг" от Haskell.
Дениз Доган,
5
Также стоит отметить, что если он, будучи специалистом по философии, имеет большой опыт работы с формальной логикой, помощники по доказательству в стиле Карри-Ховарда вполне могут быть для него менее сложными, чем для большинства опытных программистов!
CA McCann,
11

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

  • Лисп диалект для кода как-данных / homoiconicity вещи и потому , что они хороши, если не лучший, примеры динамических (более или менее строгие) функциональные языки программирования
  • Пролог как преобладающий язык логического программирования
  • Smalltalk как единственный истинный язык ООП (также интересен своим обычно чрезвычайно ориентированным на изображения подходом)
  • возможно, Erlang или Clojure, если вас интересуют языки, созданные для параллельного / параллельного / распределенного программирования
  • Forth для стек-ориентированного программирования
  • ( Haskell для строгого функционального ленивого программирования со статической типизацией)

Особенно Lisps (CL не столько, сколько Scheme) и Prolog (и Haskell) поддерживают рекурсию.

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

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

данлей
источник
Я не
вынесу
10

Как насчет стек-ориентированного языка программирования ? Кошка попадает в ваши лучшие моменты. Это:

  • Статически типизирован с выводом типа.
  • Заставляет вас переосмыслить общие концепции императивных языков, такие как цикл. Условное выполнение и цикл обрабатываются комбинаторами .
  • Вознаграждение - заставляет вас понять еще одну модель вычислений. Дает вам другой способ обдумывать и разбирать проблемы.

Доктор Доббс опубликовал небольшую статью о Кэт в 2008 году, хотя язык немного изменился.

Корбин Марч
источник
10

Если вам нужен строго типизированный Пролог, Mercury - интересный выбор. Я баловался этим в прошлом, и мне понравился другой взгляд, который он дал мне. Он также имеет модульность (какие параметры должны быть свободными / фиксированными) и детерминизм (сколько результатов есть?) В системе типов.

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

yatima2975
источник
8

Несмотря на то, что он не соответствует одному из ваших важных критериев (статическая * типизация), я собираюсь привести аргументы в пользу Python. Вот несколько причин, по которым, я думаю, вам стоит взглянуть на это:

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

Я понимаю, если вы ищете что-то еще. Например, логическое программирование, как предлагали другие, может подойти вам.


* Я предполагаю, что вы имеете в виду статическую типизацию, поскольку хотите объявить типы. Технически Python - это строго типизированный язык, поскольку вы не можете произвольно интерпретировать, скажем, строку как число. Интересно, что существуют производные Python, допускающие статическую типизацию, например Boo .

Тим Йейтс
источник
Однако строгая система типов не обязательно означает только «статическую» типизацию.
Дениз Доган,
+1 также см. Мой комментарий к ответу Ларсманса. Но будьте осторожны, рекламируя Python как достаточно функциональный. Например, выражение генератора, как правило , предпочтительнее map, filterи т.д. Но все же, генераторы и выражение генератора будут чувствовать себя знакомы с кем - то , кто знает , что ленивые вычисления и сказал функцию.
16
В самом деле? Я думаю, что Python в основном кажется особенно функциональным людям, которые мало занимались функциональным программированием. Я довольно часто использовал как Python, так и Haskell, и хотя Python - хороший язык и, безусловно, позаимствовал кое-что из функциональных языков, он по-прежнему необходим на 99%.
CA McCann,
@camccann Вы правы - у меня другая точка зрения, поэтому я предлагаю это как интересную альтернативу. Как человек, первым изучивший императивное программирование, я понимаю, что Python позволяет мне использовать функциональные методы там, где они подходят, и избегать их там, где есть смысл в другом. Я не утверждаю, что это "функционально", а только то, что это хороший компромисс.
Тим Йейтс,
Привычки, полученные с помощью Haskell, могут сделать вас гораздо лучшим программистом на Python, чем те, кто выучил его как первый язык.
u0b34a0f6ae
8

Я бы порекомендовал вам Erlang. Это не строго типизированный язык, и вам стоит его попробовать. Это совершенно другой подход к программированию, и вы можете обнаружить, что есть проблемы, когда строгая типизация не является лучшим инструментом (TM). В любом случае Erlang предоставляет вам инструменты для проверки статического типа (typer, dialyzer), и вы можете использовать строгую типизацию в тех частях, где вы получаете от этого выгоду. Для вас это может быть интересным опытом, но будьте готовы, это будет совсем другое ощущение. Если вы ищете «концептуально интересную парадигму», вы можете найти их в Erlang, передаче сообщений, разделении памяти вместо совместного использования, распределении, OTP, обработке ошибок и распространении ошибок вместо «предотвращения ошибок» и т.д. Если у вас есть опыт работы с C и Haskell, Erlang может быть далек от вашего текущего опыта, но все равно будет вызывать раздражение.

Гинек-Пичи-Выходил
источник
8

Учитывая ваше описание, я бы предложил Ocaml или F # .

Семейство ML обычно очень хороши с точки зрения сильной системы типов. Акцент на рекурсию в сочетании с сопоставлением с образцом также очевиден.

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

Если бы вы не наложили свои ограничения, я бы предложил Python или Erlang , оба из которых выведут вас из зоны комфорта.

Мухаммад Алькарури
источник
6

По моему опыту, строгая типизация + акцент на рекурсии означает еще один функциональный язык программирования. С другой стороны, мне интересно, очень ли это полезно, учитывая, что ни один из них не будет таким «чистым», как Haskell.

Как предлагали другие плакаты, Пролог и Лисп / Схема хороши, хотя оба динамически типизированы. В частности, о Scheme было опубликовано много замечательных книг с сильным теоретическим «вкусом» к ним. Взгляните на SICP , который также передает много общих знаний в области информатики (мета-круговые интерпретаторы и т.п.).

Фред Фу
источник
4
+1 за первый абзац, именно то, что я подумал, когда прочитал вопрос. Ради изучения новых вещей я бы предложил современный императивный язык, такой как Python - тем более, что это не то, к чему привык OP (динамическая типизация, итераторы повсюду и т. Д.). Он также имеет очень крутые продвинутые концепции, такие как метаклассы или генераторы (которые поразительно похожи на ленивые списки) / выражения генератора (которые служат как обобщение понимания списков + генераторы). Кроме того, диктуйте и устанавливайте правила понимания.
3
@delnan: Haskell также имеет понимание списков, и генераторы / итераторы могут быть легко выражены в Haskell с использованием стандартного типа списка Haskell. Таким образом, самые большие различия между двумя языками, на мой взгляд, заключаются в объектно-ориентированном программировании и (чаще всего) в нечистых структурах данных, таких как словари.
Дениз Доган,
1
@ Дениз Доган: не забывайте об отсутствии деклараций и правильной лексической области видимости в Python.
Фред Фу,
5

Вы можете начать изучать Лисп .

Пролог - тоже классный язык.


источник
5

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

Правда, это не соответствует вашим предубеждениям относительно того, чего вы хотите, но взгляните на это. Просто зная, что это где-то есть, стоит узнать. Единственным источником полных реализаций является J Software, jsoftware.com.

калейдский
источник
0

Выбирайте один из основных потоков. Учитывая доступные ресурсы, будущую конкурентоспособность ваших навыков, богатую экосистему разработчиков, я думаю, вам следует начать с Java или C # .

Ангкор-Ват
источник
14
По сравнению с Haskell, оба являются довольно хромыми языками IMO.
missingfaktor
9
Просить Haskeller переехать на Java - все равно что просить Билла Гейтса переехать в трущобы. : - /
missingfaktor
1
+1 За предложение чего-то, что определенно приведет к отрицательному рейтингу. Java и C # имеют хорошие экосистемы, и оба очень рекомендуются для серьезной работы. В качестве несомненного плюса вы можете использовать свои знания Haskell (, Java и C #) при использовании Clojure на JVM или F # в среде CLR.
ponzao
6
@ponzao: Угу, нет, предлагать кому-то перейти с Haskell на Java или C # просто ужасно и жестоко. Scala, F # и Clojure - гораздо более приятные языки со всеми теми же преимуществами, которые дает работа на JVM / CLR.
CA McCann,
5
Для аналитической философии Java или C # - пустая трата времени.
MaD70 08
0

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

Как и вы, о C и ему подобных не может быть и речи.

Я колебался между Python и Ruby как двумя практическими рабочими языками сценариев сегодня (мулы?), У которых есть некоторые функциональные компоненты, чтобы я был счастлив. Не говоря уже о дискуссиях о Rubyist / Pythonist здесь, но мой личный прагматический ответ на этот вопрос:

Изучите тот (Python или Ruby), который вы сначала получите повод подать заявку.

jdo
источник