Подтвердить что ты не робот

Отличительные черты функциональных языков

Известно, что все функциональные языки обладают некоторыми базовыми свойствами, такими как использование функций в качестве основного блока построения для программ со всеми последствиями, такими как использование рекурсии вместо итерации. Однако существуют и некоторые фундаментальные различия. Lisp использует единственное представление для кода и данных Lisp, тогда как ML не имеет стандартного представления кода ML. Erlang имеет встроенный актерский дизайн concurrency. У Хаскелла есть монады. Haskell делает различие в системе статического типа между чистыми и нечистыми функциями; ML не делает.

Каковы отличительные основные различия между другими функциональными языками (Clojure, F #, Arc, любой другой)? Под фундаментальным я подразумеваю то, что влияет на то, как вы развиваетесь на этом языке, а не, например, интегрировано ли оно с какой-то широко распространенной средой выполнения.

4b9b3361

Ответ 1

Сверху моей головы:

  • ленивый против нетерпения (ака нестойкий или строгий или по требованию по отношению к вызову по значению): аргументы функции, которые были вычислены перед приложением функции, или после или никогда?
  • чистый против нечистого: позволяет ли язык давать побочные эффекты? Имеет ли он изменяемые ссылки?
  • static vs. dynamic: существуют ли типы проверки языка во время компиляции или времени выполнения?
  • алгебраические типы данных: соответствует ли соответствие шаблону поддержки вариантам типов?
  • metaprogramming: язык предоставляет мощную систему генерации кода?
  • concurrency и parallelism: есть потоков/процессов первоклассная абстракция? Позволяет ли язык легко запускать несколько вычислений одновременно?
  • "экзотические" типы: насколько выразительной является система статического типа? GADTs? Зависимые типы? Линейные типы? Система F?

Только первые два элемента действительно уникальны для функциональных языков (т.е. почти все императивные языки нетерпеливы и нечисты).

Ответ 2

Мне нравится ответ Криса Конвей, в котором указаны некоторые важные оси, которые помогают классифицировать разные функциональные языки.

Что касается особенностей конкретных языков, я выберу F #, чтобы вызывать некоторые функции, не найденные в многие другие FPL:

  • Активные шаблоны: несколько FPL имеют алгебраические типы данных и сопоставление с образцами, но функция F #, называемая "активные шаблоны", позволяет вам определять новые шаблоны, которые позволяют использовать синтаксис соответствия шаблону произвольные данные.
  • Выражения вычисления: F # имеет красивый синтаксический сахар для создания монадического кода; хотя система типов не может выражать более высокий тип полиморфизма (без абстракции над конструкторами типов), поэтому вы не можете писать код для произвольной монады M, код, который вы можете написать для фиксированной монады, очень крут, и люди пишут некоторые большие соображения в монады seq {} или async {}.
  • Котировки: обычный бит "code as data for metaprogramming", хотя F # имеет выразительную систему статического типа и богатый синтаксис, и я не уверен, как много не-lisps могут это сделать.

В терминах общей классификации F # является

  • eager (строгий, по умолчанию, но "ленивый" - это ключевое слово и библиотека, а использование seq/IEnumerable для некоторой лени - общая стратегия)
  • нечистый (хотя синтаксис смещает вас к стилю более чистого по умолчанию)
  • static (с типом вывода, поэтому F # часто "чувствует себя как скриптинг", только с безопасностью типа)

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

  • Интеграция Visual Studio означает отличное редактирование (например, Intellisense)
  • Интеграция с Visual Studio означает отличную работу по отладке (например, точки останова/точки трассировки, локали, немедленное окно,...)
  • REPL для сценариев или UI-на-лету - это горячая точка (fsi.exe command-line или "F # Interactive", встроенная в VS)
  • Средство интеграции .NET для большинства "X" уже есть библиотека для этого
  • боковые инструменты, такие как FsLex/FsYacc, и интеграция с MSBuild, которая упрощает "сборку"

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

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

Ответ 3

  • Нестрогая и строгая оценка.

  • Статическая и динамическая типизация.

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

  • Производные Хиндли-Милнера против других алгоритмов вывода статического типа. SML, OCaml, Haskell и F # используют алгоритмы вывода типа на основе Hindley-Milner, тогда как Scala имеет только локальный тип вывода (например, С# 3) и требует компиляции большего количества аннотаций. (Код Haskell часто заполняется аннотациями типа на уровне функций, но большинство из них не нужны и добавляются для документации и помогают компилятору в наличии ошибок).

  • Соответствие шаблону vs manual деконструкция. SML, OCaml, F #, Haskell, Mathematica и Scheme автоматизировать деконструкцию значения.

  • Закрытые типы сумм против только открытых типов сумм. SML, OCaml, F # и Haskell позволяют определять замкнутые/запечатанные алгебраические типы для усиления статической типизации, неявно передавая более конкретные ограничения. OCaml и F # также допускают открытые типы сумм, тогда как SML этого не делает, и Haskell требует сложного обходного пути (описанного Олегом Киселевым).

  • Границы ограниченного времени. Совпадение шаблонов происходит очень быстро в SML и (vanilla) OCaml, но имеет неизвестную производительность в F # из-за активных шаблонов и даже неизвестной асимптотической сложности в Mathematica.

  • Компиляция на лету код. F #, Lisp и схема позволяют код сгенерировать, скомпилировать и эффективно выполняются во время выполнения.

  • Макросы. OCaml, Mathematica, Lisp и Схема - расширяемые языки.

  • Стандартизованный vs запатентованный. SML, Haskell 2010, Common Lisp и Scheme являются стандартизованными языками, тогда как OCaml, Erlang, F # и Mathematica являются собственностью.

Ответ 4

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

  • Динамически типизированная vs статическая, полиморфная система типов с алгебраическими типами данных и типом вывода. Система статического типа несколько ограничивает код, но имеет много преимуществ:
    • Типы - это документация, проверенная компилятором.
    • Система типов поможет вам выбрать, какой код будет писать дальше, а когда вы не уверены, что именно писать, система типов поможет вам легко и быстро исключить многие альтернативы.
    • Мощная современная система полиморфного типа необоснованна хороша в обнаружении небольших, глупых, теряющих время ошибок.
  • Ленивая оценка по умолчанию везде против ленивой оценки ограничивается тщательно контролируемыми конструкциями.
    • Lazy vs eager имеет огромные последствия для вашей способности прогнозировать и понимать затраты времени и пространства ваших программ.
    • На полностью ленивом языке вы можете полностью отделить производство данных от решений о том, что делать с данными, которые когда-то были созданы. Это особенно важно для задач поиска, поскольку упростить модульность и повторное использование кода становится намного проще.

Ответ 5

Функциональное программирование - это стиль, а не языковая конструкция

Большинство функциональных языков имеют некоторые общие принципы:

  • Неизменяемые объекты
  • Закрытия и анонимные функции
  • Общие алгоритмы
  • Продолжения

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

Ответ 6

Основные свойства?

  • Функциональная чистота (отсутствие побочных эффектов)
  • В качестве связующего из вышеизложенного отсутствует состояние.
  • Совместимость шаблонов в функциях

Первое красиво, второе - уродливое побочное действие первого (каламбур).

Реальная компенсация за отсутствие состояния - это то, что я считаю самым большим отличием между функциональными языками.

Те немногие вещи дают много бесплатных. В большинстве случаев языки обрабатывают memoization.

Ответ 7

Когда вы говорите, что код как данные, вы имеете в виду язык, где код представлен в структуре данных. Это называется Homoiconicity, и это обычно верно только для языков, которые являются диалогими lisp или чем-то близким к нему. Haskell, Erlang и Scala не являются Homoiconic, Clojure is.

Clojure Основные отличия:

  • У этого есть система Программной Транзакционной Памяти, которая облегчает совместное программирование общего состояния

  • Это Lisp, в отличие от Haskell или Erlang, поэтому весь код - это данные, которые позволяют вам делать то, что нравится, нравится изменениям самого языка во время выполнения через макросистему

  • Он запускается на JVM, что означает, что вы имеете прямой доступ ко всем библиотекам Java

  • Clojure структуры данных реализуют интерфейсы Java, такие как Collection, List, Map, Runnable и Callable, где это необходимо. Строки - это только строки Java, числа - это целые числа и пары Java. Это означает, что структуры данных Clojure могут передаваться непосредственно в библиотеки Java без каких-либо переходов или перевода