Haskell или стандартный ML для начинающих? [закрытый]
Я собираюсь преподавать курс с более низким разделением в дискретных структурах. Я выбрал учебник дискретные структуры, логика и вычислимость отчасти потому, что он содержит примеры и концепции, которые способствуют реализации с функциональным языком программирования. (Я также думаю, что это хороший учебник.)
Я хочу простой для понимания язык FP, чтобы проиллюстрировать концепции DS и что студенты могут использовать. Большинство студентов будет иметь только один или два семестра программирования на Java, в лучшем случае. Посмотрев на Scheme, Erlang, Haskell, Ocaml и SML, я остановился на Haskell или Standard ML. Я склоняюсь к Haskell по причинам, изложенным ниже, но мне хотелось бы услышать мнение тех, кто является активными программистами в одном или другом.
- как Haskell, так и SML имеют сопоставление шаблонов, что делает описание рекурсивного алгоритма подпругой.
- Haskell имеет хороший список понимания, которые хорошо сочетаются с то, как такие списки выражаются математически.
- Haskell имеет ленивую оценку. Отлично подходит для построения бесконечных списков с использованием метода понимания списка.
- SML имеет действительно интерактивный интерпретатор, в котором функции могут быть определены и использованы. В Haskell функции должны быть определены в отдельном файле и скомпилировать перед использованием в интерактивной оболочке.
- SML дает явное подтверждение аргумента функции и возвращаемых типов в синтаксисе это легко понять. Например: val foo = fn: int * int - > int. Неявный синтаксис Карри Хаскелла немного более тупой, но не совсем чужой. Например: foo :: Int - > Int - > Int.
- по умолчанию Haskell использует целые числа произвольной точности. Это внешняя библиотека в SML / NJ. И SML / NJ усекает вывод до 70 символов по умолчанию.
- лямбда-синтаксис Хаскелла тонкий - он использует одну обратную косую черту. SML является более явным. Не уверен, что нам когда-нибудь понадобится лямбда хотя этот класс.
по существу, SML и Haskell примерно эквивалентны. Я склоняюсь к Хаскеллу, потому что мне нравится понимание списка и бесконечные списки в Хаскелле. Но я беспокоюсь, что большое количество символов в компактном синтаксисе Haskell может вызвать проблемы у студентов. Из того, что я собрал, читая другие сообщения на SO, Haskell не рекомендуется для начинающих, начинающих с FP. Но мы не собираемся создавать полноценные приложения, просто пытаемся вышли простые алгоритмы.
что вы думаете?
Edit: прочитав некоторые из ваших замечательных ответов, я должен прояснить некоторые из моих основных пунктов.
в SML нет синтаксического различия между определением функции в интерпретаторе и определением ее во внешнем файле. Допустим, вы хотите написать функцию факториал. В Haskell вы можете поместить это определение в файл и загрузить его в GHCi:
fac 0 = 1
fac n = n * fac (n-1)
для меня, это ясно, сжато, и соответствует математическому определению в книге. Но если вы хотите написать функцию в GHCi напрямую, вы должны использовать другой синтаксис:
let fac 0 = 1; fac n = n * fac (n-1)
при работе с интерактивными переводчиками, с точки зрения обучения это очень, очень удобно, когда студент может использовать один и тот же код как в файле, так и в командной строке.
под "явным подтверждением функции" я имел в виду, что при определении функции SML сразу сообщает вам имя функции, типы аргументов и возвращаемый тип. В Haskell вы должны использовать :type
команда, а затем вы получаете несколько запутанную нотацию Карри.
еще одна интересная вещь о Haskell - это допустимое определение функции:
fac 0 = 1
fac (n+1) = (n+1) * fac n
опять же, это соответствует определению, которое они могут найти в учебнике. Не могу сделать это в SML!
8 ответов:
как бы я ни любил Haskell, вот причины, по которым я бы предпочел SML для класса в дискретной математике и структурах данных (и большинство других классов для начинающих):
затраты времени и пространства программ Haskell может быть очень трудно предсказать, даже для экспертов. SML предлагает гораздо более ограниченные способы взорвать машину.
синтаксис для определения функций в интерактивном интерпретаторе одинаковых на синтаксис, используемый в файле, так что вы можете вырезать и вставить.
хотя перегрузка оператора в SML полностью фиктивна, это также просто. Это будет трудно преподавать целый класс в Haskell без необходимости попасть в классы типа.
студент может отлаживать с помощью
Debug.Trace.trace
.)бесконечные структуры данных взрывают умы людей. Для начинающих, вам лучше, чтобы они определяли тип потока в комплекте с ячейками ref и thunks, поэтому они знают, как это работает:
datatype 'a thunk_contents = UNEVALUATED of unit -> 'a | VALUE of 'a type 'a thunk = 'a thunk_contents ref val delay : (unit -> 'a) -> 'a thunk val force : 'a thunk -> 'a
теперь это уже не магия, и вы можете перейти отсюда к потокам (бесконечные списки).
макет не так прост, как в Python, и может быть запутанным.
есть два места в Haskell ребром:
в core Haskell вы можете написать подпись типа функции непосредственно перед его определение. Это очень полезно для студентов и других начинающих. Просто нет хорошего способа справиться с сигнатурами типов в SML.
Haskell имеет лучший конкретный синтаксис. Синтаксис Haskell-это значительное улучшение по сравнению с синтаксисом ML. Я написал короткая заметка о том, когда использовать круглые скобки в программе ML; это немного помогает.
наконец, есть меч, который режет обоих способы:
- код Haskell по умолчанию чист, поэтому ваши ученики вряд ли случайно наткнутся на нечистые конструкции (IO monad, state monad). Но по той же причине они не могут печатать, и если вы хотите сделать ввод-вывод, то в minumum вы должны объяснить
do
нотации, иreturn
сбивает с толку.
по смежной теме, Вот несколько советов для подготовки курса: не забывайте Чисто Функциональные Структуры Данных Крис Окасаки. Даже если у вас нет ваших студентов использовать его, вы определенно хотите иметь копию.
мы учим Хаскелла на первых курсах в нашем университете. Мои чувства немного смешанные. С одной стороны, обучение Хаскелла на первых курсах означает, что им не нужно разучиваться императивному стилю. Haskell также может создавать очень сжатый код, который могут оценить люди, у которых раньше была Java.
некоторые проблемы, которые я заметил, студенты часто имеют:
сопоставление с образцом может быть немного трудным, сначала. У студентов изначально были некоторые проблемы просмотр того, как связаны построение значений и сопоставление шаблонов. У них также были некоторые проблемы с различением абстракций. Наши упражнения включали в себя функции записи, которые упрощают арифметическое выражение, и некоторые студенты с трудом видели разницу между абстрактным представлением (например,
Const 1
) и представление метаязыка (1
).кроме того, если ваши студенты должны сами писать функции обработки списка, будьте осторожны, указывая разница между узорами
[] [x] (x:xs) [x:xs]
в зависимости от того, сколько функционального программирования вы хотите научить их по пути, вы можете просто дать им несколько библиотечных функций и позволить им поиграть с этим.
мы не учили наших студентов анонимным функциям, мы просто рассказывали им о
where
положения. Для некоторых задач это было немного многословно, но в остальном работало хорошо. Мы также не говорили им о частичных приложениях; это, вероятно, довольно легко объяснить в Haskell (из-за его формы типов письма), поэтому, возможно, стоит показать им.они быстро обнаружили понимание списка и предпочли их более высоким функциям, таким как
filter
,map
,zipWith
.Я думаю, что мы пропустили немного учить их, как позволить им направлять свои мысли на типы. Я не совсем уверен, что это полезно для начинающих или не.
сообщения об ошибках, как правило, не очень полезны для начинающих, они могут иногда нужна помощь с ними. Я сам не пробовал, но есть компилятор Haskell, специально предназначенный для новичков, в основном с помощью лучших сообщений об ошибках:гелий
для маленьких программ, такие вещи, как возможные утечки пространства не проблема.
в целом, Хаскелл-хорошее учение язык, но есть несколько подводных камней. Учитывая, что студенты чувствуют себя намного более комфортно с пониманием списка, чем функции более высокого порядка, это может быть аргумент, который вам нужен. Я не знаю, как долго длится ваш курс или сколько программ вы хотите научить их, но запланируйте некоторое время для обучения их основным концепциям-им это понадобится.
кстати,
# SML имеет действительно интерактивный переводчик, в котором функции могут быть оба определены и используются. в Haskell, функции должны быть определены в отдельный файл и скомпилировать до используется в интерактивной оболочке.
является неточной. Используйте GHCi:
Prelude> let f x = x ^ 2 Prelude> f 7 49 Prelude> f 2 4
есть также хорошие ресурсы для Haskell в области образования на haskell.org Эду. страница, с опытом от разных учителей. http://haskell.org/haskellwiki/Haskell_in_education
наконец, вы сможете научить их многоядерному параллелизму просто для удовольствия, если вы используете Haskell : -)
многие университеты преподают Haskell как первый функциональный язык или даже первый язык программирования, поэтому я не думаю, что это будет проблемой.
сделав некоторые из преподавания на одном таком курсе, я не согласен с тем, что возможные путаницы, которые вы идентифицируете, настолько вероятны. Наиболее вероятными источниками ранней путаницы являются ошибки синтаксического анализа, вызванные плохой компоновкой, и таинственные сообщения о классах типов, когда числовые литералы используются неправильно.
Я бы тоже не согласен с любым предложением, что Haskell не рекомендуется для начинающих, начиная с FP. Это, конечно, подход Большого взрыва таким образом, что строгие языки с мутацией не являются, но я думаю, что это очень правильный подход.
- SML имеет действительно интерактивный интерпретатор, в котором функции могут быть определены и использованы. В Haskell функции должны быть определены в отдельном файле и скомпилировать перед использованием в интерактивной оболочке.
хотя объятия могут иметь это ограничение, GHCi не делает:
$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> let hello name = "Hello, " ++ name Prelude> hello "Barry" "Hello, Barry"
есть много причин, по которым я предпочитаю GHC(i) над объятиями, это только одна из них.
- SML дает явное подтверждение аргумент функции и возвращаемые типы в синтаксисе, который легко понять. Например: val foo = fn: int * int - > int. Неявный синтаксис Карри Хаскелла немного более тупой, но не совсем чужой. Например: foo :: Int - > Int - > Int.
SML также имеет синтаксис, который вы называете "неявным Карри".
$ sml Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009] - fun add x y = x + y; val add = fn : int -> int -> int
по существу, SML и Haskell примерно эквивалентны. Я склоняюсь к Хаскеллу, потому что мне нравится понимание списка и бесконечные списки в Haskell. Но я беспокоюсь, что большое количество символов в компактном синтаксисе Haskell может вызвать проблемы у студентов. Из того, что я собрал, читая другие сообщения на SO, Haskell не рекомендуется для начинающих, начинающих с FP. Но мы не собираемся создавать полноценные приложения, просто пробуя простые алгоритмы.
мне нравится использовать Haskell гораздо больше, чем SML, но я все равно сначала научу SML.
- прикомандирования мысли номиноло, список постижений do кажется, чтобы замедлить студентов от получения некоторых функций более высокого порядка.
- если вы хотите, лень и бесконечные списки, это поучительно, чтобы реализовать это явно.
- поскольку SML с нетерпением оценивается, модель выполнения намного легче понять, и "отладка через printf" работает намного лучше, чем в Haskell.
- система типов SML также проще. Хотя ваш класс, вероятно, не будет использовать их в любом случае, Классов типов Хаскелла еще дополнительный удар, чтобы получить более ... заставить их понять
'a
и''a
различие в SML достаточно жесткое.
большинство ответов были техническими, но я думаю, что вы должны рассмотреть хотя бы один, который не является: Haskell (как OCaml), в настоящее время, имеет большее сообщество, использующее его в более широком диапазоне контекстов. Существует также большая база данных библиотек и приложений, написанных для получения прибыли и удовольствия в Hackage. Это может быть важным фактором в том, чтобы некоторые из ваших студентов использовали язык после завершения курса и, возможно, пытались использовать другие функциональные языки (например, стандартный ML) позже.
Я удивлен, что вы не рассматриваете OCaml и F#, учитывая, что они решают так много ваших проблем. Конечно, достойные и полезные среды разработки являются высоким приоритетом для учащихся? SML намного отстает, и F# намного опережает все другие FPLs в этом отношении.
кроме того, как OCaml, так и F# имеют понимание списка.
Хаскел. Я впереди в своем классе algos / theory В CS из-за того, что я узнал из использования Haskell. Это такой всеобъемлющий язык, и он научит вас тонне CS,просто используя его.
тем не менее, SML гораздо легче учиться. Haskell имеет такие функции, как ленивые структуры оценки и управления, которые делают его гораздо более мощным, но с ценой крутой кривой обучения(ish). SML не имеет такой кривой.
тем не менее, большая часть Хаскелла была отучение от менее научных / математических языков, таких как Ruby, ObjC или Python.