Вопрос

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

Мне нужен простой для понимания язык FP, который иллюстрирует концепции DS и который смогут использовать студенты.Большинство студентов в лучшем случае изучали программирование на Java всего один или два семестра.Посмотрев на Scheme, Erlang, Haskell, Ocaml и SML, я остановился на Haskell или Standard ML.Я склоняюсь к Haskell по причинам, изложенным ниже, но мне хотелось бы узнать мнение тех, кто активно программирует в том или ином направлении.

  • И Haskell, и SML имеют сопоставление с образцом, что упрощает описание рекурсивного алгоритма.
  • Haskell имеет хорошее понимание списков, которое хорошо сочетается с математическим выражением таких списков.
  • В Haskell есть ленивая оценка.Отлично подходит для создания бесконечных списков с использованием техники понимания списков.
  • SML имеет по-настоящему интерактивный интерпретатор, в котором функции можно как определять, так и использовать.В Haskell функции должны быть определены в отдельном файле и скомпилированы перед использованием в интерактивной оболочке.
  • SML дает явное подтверждение аргумента функции и типов возвращаемого значения с помощью простого для понимания синтаксиса.Например:вал foo = fn:интервал * интервал -> интервал.Неявный синтаксис карри в Haskell немного более тупой, но не совсем чуждый.Например:фу ::Инт -> Инт -> Инт.
  • Haskell по умолчанию использует целые числа произвольной точности.Это внешняя библиотека в SML/NJ.А SML/NJ по умолчанию усекает вывод до 70 символов.
  • Лямбда-синтаксис Haskell утончен — он использует одну обратную косую черту.SML более явный.Однако не уверен, понадобится ли нам когда-нибудь лямбда в этом классе.

По сути, SML и Haskell примерно эквивалентны.Я склоняюсь к Haskell, потому что мне нравится понимание списков и бесконечные списки в Haskell.Но я обеспокоен тем, что большое количество символов в компактном синтаксисе Haskell может вызвать проблемы у студентов.Судя по тому, что я понял, читая другие статьи по SO, Haskell не рекомендуется новичкам, начинающим с FP.Но мы не собираемся создавать полноценные приложения, а просто опробуем простые алгоритмы.

Что вы думаете?


Редактировать:Прочитав некоторые из ваших замечательных ответов, я должен прояснить некоторые из моих пунктов.

В 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 этого сделать невозможно!

Это было полезно?

Решение

Как бы я ни любил 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:

  • В ядре Haskell вы можете написать сигнатуру типа функции непосредственно перед ее определением.Это очень полезно для студентов и других новичков.В SML просто не существует хорошего способа справиться с сигнатурами типов.

  • Haskell имеет более конкретный синтаксис.Синтаксис Haskell представляет собой значительное улучшение по сравнению с синтаксисом ML.Я написал короткое примечание о том, когда использовать круглые скобки в программе ML;это немного помогает.

Наконец, есть меч, который режет в обе стороны:

  • Код Haskell по умолчанию является чистым, поэтому ваши ученики вряд ли случайно наткнутся на нечистые конструкции (монаду ввода-вывода, монаду состояния).Но по той же причине они не могут печатать, и если вы хотите выполнять ввод-вывод, вам как минимум придется объяснить do обозначения и return сбивает с толку.

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

Другие советы

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

Некоторые проблемы, которые я заметил, часто возникают у студентов:

  • Поначалу сопоставление с образцом может быть немного сложным.Поначалу у студентов были некоторые проблемы с пониманием того, как связаны построение значений и сопоставление с образцом.У них также были некоторые проблемы с различием между абстракциями.Наши упражнения включали в себя написание функций, упрощающих арифметические выражения, и некоторым учащимся было трудно увидеть разницу между абстрактными представлениями (например, Const 1) и метаязыковое представление (1).

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

    []
    [x]
    (x:xs)
    [x:xs]
    

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

  • Мы не рассказывали нашим студентам об анонимных функциях, мы просто рассказывали им о них. where статьи.Для некоторых задач это было немного многословно, но в остальном работало хорошо.Мы также не рассказали им о частичных заявках;это, вероятно, довольно легко объяснить на Haskell (из-за его формы написания типов), так что, возможно, стоит показать им.

  • Они быстро открыли для себя понимание списков и предпочли их функциям более высокого порядка, таким как filter, map, zipWith.

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

  • Сообщения об ошибках обычно не очень полезны новичкам, иногда им может потребоваться помощь.Сам я не пробовал, но есть компилятор Haskell, специально ориентированный на новичков, в основном за счет более качественных сообщений об ошибках: Гелий

  • Для небольших программ такие вещи, как возможные утечки пространства, не были проблемой.

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

КСТАТИ,

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

Неточно.Используйте GHCi:

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

На сайте haskell.org edu также есть хорошие ресурсы по Haskell в образовании.страница с опытом разных учителей. http://haskell.org/haskellwiki/Haskell_in_education

Наконец, вы сможете научить их многоядерному параллелизму просто ради развлечения, если будете использовать Haskell :-)

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

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

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

  • SML имеет по-настоящему интерактивный интерпретатор, в котором функции можно как определять, так и использовать.В Haskell функции должны быть определены в отдельном файле и скомпилированы перед использованием в интерактивной оболочке.

Хотя у Hugs может быть такое ограничение, у 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) Hugs, и это лишь одна из них.

  • SML дает явное подтверждение аргумента функции и типов возвращаемого значения с помощью простого для понимания синтаксиса.Например:вал foo = fn:интервал * интервал -> интервал.Неявный синтаксис карри в Haskell немного более тупой, но не совсем чуждый.Например:фу ::Инт -> Инт -> Инт.

В 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.Но я обеспокоен тем, что большое количество символов в компактном синтаксисе Haskell может вызвать проблемы у студентов.Судя по тому, что я понял, читая другие статьи по SO, Haskell не рекомендуется новичкам, начинающим с FP.Но мы не собираемся создавать полноценные приложения, а просто опробуем простые алгоритмы.

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

  • Поддерживаем мысли номиноло, понимаем список делать кажется, что они мешают учащимся добраться до некоторых функций более высокого порядка.
  • Если вам нужны ленивость и бесконечные списки, поучительно реализовать это явно.
  • Поскольку SML тщательно оценивается, модель выполнения гораздо проще понять, а «отладка с помощью printf» работает намного лучше, чем в Haskell.
  • Система типов SML также проще.Хотя ваш класс, скорее всего, в любом случае не будет их использовать, классы типов Haskell по-прежнему представляют собой дополнительную проблему, которую нужно преодолеть — заставить их понять 'a против ''a Различие в SML достаточно жесткое.

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

Я поражен, что вы не рассматриваете OCaml и F#, поскольку они решают многие ваши проблемы.Несомненно, достойная и полезная среда разработки является главным приоритетом для учащихся?В этом отношении SML сильно отстает, а F# намного опережает все другие FPL.

Кроме того, и OCaml, и F# поддерживают понимание списков.

Хаскелл.Я впереди по уроку алгоритмов/теории в CS благодаря тому, чему научился при использовании Haskell.Это такой всеобъемлющий язык, и он научит вас множеству CS, просто используя его.

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

Тем не менее, большая часть Haskell отучилась от менее научных/математических языков, таких как Ruby, ObjC или Python.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top