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 72

8 ответов:

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

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

  • синтаксис для определения функций в интерактивном интерпретаторе одинаковых на синтаксис, используемый в файле, так что вы можете вырезать и вставить.

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

  • студент может отлаживать с помощью print. (Хотя, как отмечает комментатор, можно получить почти такой же эффект в 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.