Почему народная сказка и рамда такие разные?

Я изучаю javascript FP, читая книгу DrBoolean.

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

Но они такие разные

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

  • Однако Folktale не содержит никакой утилиты для списка или функций. Кажется, что в javascript реализованы некоторые алгебраические структуры, такие как monad: Maybe, Task...

На самом деле я нашел больше библиотек, они все, кажется, попадают в две категории. Подчеркнем, Лодаш очень похож на Рамду. Фэнтези-лэнд, бессмысленные фэнтези похожи на сказку.

Можно ли назвать эти очень разные библиотеки функциональными, и если да, то что делает каждую из них функциональной библиотекой?

1 ответ

Решение

Функциональные особенности

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

  • Первоклассные функции высшего порядка
  • Лямбда / анонимные функции с замыканиями

Другие можно выполнить в Javascript с некоторой осторожностью:

  • неизменность
  • Ссылочная прозрачность

Третьи являются частью ES6 и частично или полностью доступны прямо сейчас:

  • Компактные, даже краткие функции
  • Рекурсия перманента через оптимизацию хвостового вызова

И есть много других, которые на самом деле за пределами Javascript:

  • Сопоставление с образцом
  • Ленивая оценка
  • Homoiconicity

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

Фэнтези-лэнд

Fantasy-land - это спецификация для ряда стандартных типов, перенесенных из математической теории категорий и абстрактной алгебры в функциональное программирование, таких типов, как Monoid, Functor и Monad. Эти типы довольно абстрактны и расширяют, возможно, более знакомые понятия. Функторы, например, являются контейнерами, которые могут быть mapс функцией, как массив может быть mapиспользовать Array.prototype.map,

народная сказка

Folktale - это коллекция типов, реализующая различные части спецификации Fantasy-land, и небольшая коллекция вспомогательных функций. К этим типам относятся такие вещи, как " Возможно", " Либо", " Задача" (очень похожие на то, что в другом месте называется "Будущее", и более законный родственник "Обещанию") и " Валидация".

Folktale, пожалуй, самая известная реализация спецификации Fantasy-land, и она пользуется уважением. Но нет такой вещи как окончательная реализация или реализация по умолчанию; fantasy-land определяет только абстрактные типы, и реализация, конечно, должна создавать такие конкретные типы. Заявление Folktale о том, что он является функциональной библиотекой, очевидно: она предоставляет типы данных, которые обычно встречаются в функциональных языках программирования, которые существенно облегчают программирование функциональным образом.

Этот пример из документации Folktale показывает, как его можно использовать:

// We load the library by "require"-ing it
var Maybe = require('data.maybe')

// Returns Maybe.Just(x) if some `x` passes the predicate test
// Otherwise returns Maybe.Nothing()
function find(predicate, xs) {
  return xs.reduce(function(result, x) {
    return result.orElse(function() {
      return predicate(x)?    Maybe.Just(x)
      :      /* otherwise */  Maybe.Nothing()
    })
  }, Maybe.Nothing())
}

var numbers = [1, 2, 3, 4, 5]

var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers)
// => Maybe.Just(3)

var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers)
// => Maybe.Nothing

Ramda

Рамда (отказ от ответственности: я один из авторов) - это совсем другой тип библиотеки. Он не предоставляет новые типы для вас.1 Вместо этого он предоставляет функции, облегчающие работу с существующими типами. Он построен на понятиях объединения меньших функций в более крупные, работы с неизменяемыми данными, предотвращения побочных эффектов.

Рамда работает особенно над списками, но также и над объектами, а иногда и над строками. Он также делегирует многие свои вызовы таким образом, что он будет взаимодействовать с Folktale или другими реализациями Fantasy-land. Например, Рамда map функция, работает так же, как на Array.prototype, так R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16], Но потому что Фольклорный Maybe реализует Fantasy-land Functor spec, который также указывает карту, вы также можете использовать Рамда map с этим:

R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing

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

// :: [Comment] -> [Number]  
var userRatingForComments = R.pipe(
    R.pluck('username')      // [Comment] -> [String]
    R.map(R.propOf(users)),  // [String] -> [User]
    R.pluck('rating'),       // [User] -> [Number]
);

Другие библиотеки

На самом деле я нашел больше библиотек, они все, кажется, попадают в две категории. Подчеркнем, Лодаш очень похож на Рамду. Фэнтези-лэнд, бессмысленные фэнтези подобны сказке

Это не совсем точно. Прежде всего, Fantasy-land - это просто спецификация, которую библиотеки могут решить реализовать для различных типов. Folktale - одна из многих реализаций этой спецификации, возможно, лучшая, конечно, одна из самых зрелых. Pointfree-fantasy и ramda-fantasy - это другие, и их гораздо больше.

Underscore и lodash внешне похожи на Ramda в том смысле, что они являются библиотеками-пакетами, предоставляя множество функций с гораздо меньшей согласованностью, чем что-то вроде Folktale. И даже определенная функциональность часто совпадает с функциональностью Рамды. Но на более глубоком уровне Рамда сильно отличается от этих библиотек. Вероятно, ближайшими родственниками Рамды являются такие библиотеки, как FKit, Fnuc и Wu.js.

Билби относится к своей категории, предоставляя как ряд инструментов, таких как инструменты, предоставленные Ramda, так и некоторые типы, совместимые с Fantasy-land. (Автор Билби также является автором Fantasy-land.)

Ваш звонок

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

Некоторые из этих библиотек действительно хорошо работают вместе. Рамда должен хорошо работать с Folktale или другими реализациями Fantasy-land. Поскольку их проблемы практически не пересекаются, они на самом деле не конфликтуют, но Рамда делает достаточно, чтобы взаимодействие было относительно гладким. Это, вероятно, менее верно для некоторых других комбинаций, которые вы можете выбрать, но более простой синтаксис функции ES6 также может облегчить интеграцию.

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


1 Ну, есть побочный проект, ramda-fantasy, выполняющий что-то похожее на то, что делает Folktale, но он не является частью базовой библиотеки.

Другие вопросы по тегам