Рубрика «функциональное программирование» - 40

6-7 ноября 2014 года в Перми будет проведен конкурс «Открытый регион. Хакатон» по разработке приложений и сервисов на основе открытых данных Пермского края.

На сайте opendata.permkrai.ru опубликовано примерно 1400 статистических показателей по различным областям жизнедеятельности края. Что можно сделать с этими данными? Первая мысль, которая пришла мне в голову, — создать аналог сайта Spurious Correlations (ложные корреляции).

TL; DR:
Исходники: github.com/yakov-bakhmatov/odpr
Приложение: odpr.bakhmatov.ru/
Читать полностью »

Язык Julia не поддерживает такую технику программирования, хорошо зарекомендовавшую себя в языках Haskell, Prolog, Erlang, Scala, Mathematica, как pattern matching. Но разрешает писать макросы, которые позволяют исправить этот фатальный недостаток. Выглядит это примерно так:

julia> immutable X a end

julia> immutable Y a ; b end

julia> @case(Y(X(9),2),  Y(4,3)-> 55, Y(X(k),2)->1+k)
10

Исходный код доступен на github.
Похожую (но гораздо более развитую и готовую для использования) можно взять здесь, но она слишком большая, что бы разбирать ее как пример в статье.
Читать полностью »

Идея для Clojure Cup этого года родилась примерно вот здесь:

Как мы писали Clojure Cup в этом году: The Hat
(город Вырица, Ленобласть)

Ожидая обратную электричку мы убивали время, как могли, и грустили, что под рукой нет чего-то вроде Alias'а или Шляпы — всё же салонные игры это интеллигентнее, чем косплей гопоты в заброшке. TL;DR:

Как мы писали Clojure Cup в этом году: The Hat

Играть: http://playthehat.com (ещё с багами и не работает не на хроме, мы не можем править до окончания голосования судей)
Голосовать: https://clojurecup.com/#/apps/thehat

Более длинная версия поста — ниже.
Читать полностью »

Оригинальная статья — Understanding Monads With JavaScript (Ionuț G. Stan).
Буду признателен за комментарии об ошибках/опечатках/неточностях перевода в личку

От автора

Последние несколько недель я пытаюсь понять монады. Я все еще изучаю Haskell, и, честно говоря, думал, что знаю, что это такое, но когда я захотел написать маленькую библиотечку — так, для тренировки — я обнаружил, что хотя и понимаю, как работают монадические bind (>>=) и return, но не представляю, откуда берется состояние. Так что, вероятно, я вообще не понимаю, как это все работает. В результате, я решил заново изучить монады на примере Javascript. План был тот же, когда я выводил Y Combinator: взял изначальную задачу (здесь это взаимодействие с неизменяемым явно состоянием), и проделал весь путь к решению, шаг за шагом изменяя изначальный код.
Читать полностью »

Всем привет!

Увидел, что статья о трансдьюсерах на JavaScript стала вполне популярной и хотел отметить, что уже давно доступен генераторов парсеров на транзисторах^W трансдьюсерах. По крайней мере, очень на это похоже. У меня есть статья с подробным описанием на английском «Generating Functional Parsers» и, собственно, исходники.

Тут какие-то новые правила, постов-ссылок уже нет, просят всё обильно описывать — так что я подчинюсь и парой слов (разбавленных необходимой водой), расскажу, о чём это, а то могу ведь и не прав оказаться. Тем более русской версии статьи пока нет, да и скорее всего не будет. Одна надежда, что эта пройдёт.
Читать полностью »

В первой части мы остановились на следующей спецификации: Трансдьюсер — это функция принимающая функцию step, и возвращающая новую функцию step.

step⁰ → step¹

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

result⁰, item → result¹

Чтобы получить новый текущий результат в функции step¹, нужно вызвать функцию step⁰, передав в нее старый текущий результат и новое значение, которое мы хотим добавить. Если мы не хотим добавлять значение, то просто возвращем старый результат. Если хотим добавить одно значение, то вызываем step⁰, и то что он вернет возвращаем как новый результат. Если хотим добавить несколько значений, то вызываем step⁰ несколько раз по цепочке, это проще показать на примере реализации трансдьюсера flatten:

function flatten() {
  return function(step) {
    return function(result, item) {
      for (var i = 0; i < item.length; i++) {
        result = step(result, item[i]);
      }
      return result;
    }
  }
}

var flattenT = flatten();

_.reduce([[1, 2], [], [3]], flattenT(append), []); // => [1, 2, 3]

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

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

Итак, сейчас мы можем:

  1. Изменять элементы (прим. map)
  2. Пропускать элементы (прим. filter)
  3. Выдавать для одного элемента несколько новых (прим. flatten)

Читать полностью »

Рич Хикки, автор языка Clojure, недавно придумал новую концепцию — Трансдьюсеры. Их сразу добавили в Clojure, но сама идея универсальна и может быть воспроизведена в других языках.

Сразу, зачем это нужно:

  • трансдьюсеры могут улучшить производительность, т.к. позволят не создавать временные коллекции в цепочках операций map.filter.takeWhile.etc
  • могут помочь переиспользовать код
  • могут помочь интегрировать библиотеки между собой, например underscore/LoDash могут уметь создавать трансдьюсеры, а FRP библиотеки (RxJS/Bacon.js/Kefir.js) могут уметь их принимать
  • могут упростить FRP библиотеки, т.к. можно будет выбросить кучу методов, добавив один метод для поддержки трансдьюсеров

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

Читать полностью »

Наверняка многие уже слышали о подходе FRP для организации асинхронного кода. На хабре уже писали об FRP (Реактивное программирование в Haskell, FRP на Bacon.js) и есть хорошие доклады на эту тему (Программировние UI с помощью FRP и Bacon.js, Functional Reactive Programming & ClojureScript, О Bacon.js от Juha Paananen — автора бекона)

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

Вот что это дает по сравнению с обратными вызовами:

1) Поток событий (Event stream) и значение меняющаяся во времени (Property / Behavior) становятся объектами первого класса. Это значит что их можно передавать в функции и возвращать из функций.

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

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

К примеру можно написать функцию, возвращающую поток перетаскиваний (drag). В качестве параметров она будет принимать 3 потока — начало перетаскивания, движение, конец перетаскивания. Дальше можно передать в эту функцию: либо потоки для соответствующих событий мыши (mousedown, mousemove, mouseup), либо для touch событий (touchstart, touchmove, touchend). Сама же функция не будет ничего знать об источниках событий, а будет работать только с абстрактными потоками. Пример реализации на Bacon.

2) Явный state

Второе большое преимущество FRP это явное управление состоянием. Как известно, state — один из самых главных источников сложности программ, поэтому грамотное управление им позволяет писать более надежные и простые в поддержке программы. Отличный доклад от Рича Хикки о сложности (complexity) «Simple Made Easy».

FRP позволяет писать бОльшую часть кода на «чистых функциях» и управлять потоком данных (dataflow) явно (с помощью потоков событий), а состояния хранить тоже явно в Property.

Читать полностью »

Компания Wolfram Research открыла сервис Tweet a Program: интересных программ на языке Wolfram Language, длина которых не превышает 140 символов

В языке Wolfram Language небольшой код может делать крайне много. Используя это, мы сделали сервис, который позволит вам получить от этого удовольствие, сегодня мы открываем его — Tweet-a-Program.

Этот сервис соединяет в себе программы на языке Wolfram Language длиной в одно сообщение твиттера и возможность их автоматической отправки в @WolframTaP. Наш Твиттер-бот запустит вашу программу в Wolfram Cloud (Облаке Wolfram), после чего опубликует результат.

Hello World from Tweet-a-Program: GeoGraphics[Text[Style[&quot;Hello!&quot;,150]],GeoRange->&quot;World&quot;]
Читать полностью »

(пятница)
Всё началось с того, что я прочитал у Станислава Лема в романе «Мир на Земле» (1985), что в будущем общение на языке будет заменено общением при помощи пиктограмм. Мне показалось это довольно пророческим в связи с возрастающим интересом к различным смайликам и другим видам более крупных картинок и я подумал: а что если программировать при помощи emoji? Поискав в сети я убедился, что мысль такая уже приходила в головы людей и воплотилась в проект https://github.com/wheresaddie/Emojinal
но этот проект меня не впечатлил, во-первых язык не обладает полнотой и вообще подход автора как попытка заменить часть операторов при помощи emoji показалась не сильно интересной.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js