Pull to refresh

Реактивное программирование

Reading time 7 min
Views 34K
Haskell *
Как известно, функциональный подход к программированию имеет свою специфику: в нём мы преобразовываем данные, а не меняем их. Но это накладывает свои ограничения, например при создании программ активно взаимодействующих с пользователем. В императивном языке намного проще реализовать такое поведение, ведь мы можем реагировать на какие либо события «в реальном времени», в то время как в чистых функциональных языках нам придётся откладывать общение с системой до самого конца. Однако относительно недавно стала развиваться новая парадигма программирования, решающая эту проблему. И имя ей — Functional Reactive Programming (FRP). В этой статье я попытаюсь показать основы FRP на примере написания змейки на Haskell с использованием библиотеки reactive-banana.
Читать дальше →
Total votes 27: ↑26 and ↓1 +25
Comments 18

Битва за Кложуру или операция «Боевой Магнит»

Reading time 6 min
Views 5K
Self Promo
Участвовали в Clojure Cup 2013 вместе с Саней ingspree, Сергеем Joes и Ромой rofh. Наверное, вы видели нарезку, а может и полное выступление Сани о кложурскрипте и реактивном программировании. Вот и подвернулась возможность попробовать эти технологии в бою.

Тематика соревнования — за 48 часов напилить что-нибудь, используя Clojure или ClojureScript. Из разных вариантов решено было пилить браузерный Risk, в частности потому, что все существующие приложения убоги интерфейсом, или написаны на Flash, или, ещё того хуже — Silverlight, или ещё каким-нибудь образом портят времяпровождение. Коллективно придумалось хорошее название — War Magnet.

Недолго думая, мы решили писать и сервер на Clojure, и клиент на ClojureScript, с использованием общего кода. Из четырёх участников только у Сани был хоть какой-то опыт написания на кложуре, а у остальных был только опыт решения нескольких десятков задачек на 4clojure.
Под катом есть три раздела - о серверной части, клиентской и о самом соревновании.
Total votes 42: ↑40 and ↓2 +38
Comments 19

FRP (functional reactive programming) на Bacon.js

Reading time 6 min
Views 25K
JavaScript *Functional Programming *
Sandbox
Часто, при создании достаточно сложных приложений на JavaScript наступает тот момент, когда становиться совершенно непонятно почему приложение перестало работать как надо, или наоборот вдруг заработало. Cвязей между элементами приложения становится так много, что уследить за ними даже с хорошими дебаггером очень трудно. И вот диллема: с одной стороны есть хорошо известная методика создания приложений на JS, столь привычная и глубоко описанная, что недостатков мы уже как бы и не замечаем. С другой стороны есть масса библиотек предлагающих нам перейти на другую сторону попробовать что-то новое. К таким библиотекам относиться и Bacon.js, предоставляя реализацию FRP на JavaScript.
Читать дальше →
Total votes 17: ↑17 and ↓0 +17
Comments 17

Курс «Принципы реактивного программирования» на coursera.org

Reading time 7 min
Views 35K
Designing and refactoring *Scala *Functional Programming *
Sandbox
Принципы реактивного программирования Я хочу рассказать о современной дисциплине программирования, отвечающей растущим требованиям масштабируемости, отказоустойчивости и быстрого отклика, и незаменимой как в многоядерных средах, так и в облачных вычислениях, а также представить вам открытый онлайн-курс по ней, который начнётся всего через несколько дней.

Читать дальше →
Total votes 23: ↑13 and ↓10 +3
Comments 10

Атом — минимальный кирпичик реактивного приложения

Reading time 15 min
Views 45K
JavaScript *Programming *Algorithms *
Recovery mode
Здравствуйте, меня зовут Дмитрий Карловский и я… клиент-сайд разработчик. За плечами у меня 8 лет поддержки самых различных сайтов и веб-приложений: от никому не известных интернет-магазинов, до таких гигантов как Яндекс. И всё это время я не только фигачу в продакшн, но и точу топор, чтобы быть на самом острие технологий. А теперь, когда вы знаете, что я не просто хрен с горы, позвольте рассказать вам про один архитектурный приём, которым я пользуюсь последний год.

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

Осторожно: чтение может вызвать вывих мозга, приступ холивара, а также бессонные ночи рефакторинга.
Читать дальше →
Total votes 55: ↑49 and ↓6 +43
Comments 36

Kefir.js — новая библиотека для функционального реактивного программирования (FRP) в JavaScript

Reading time 4 min
Views 22K
JavaScript *Programming *Functional Programming *
Наверняка многие уже слышали о подходе 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.

Читать дальше →
Total votes 34: ↑30 and ↓4 +26
Comments 19

Трансдьюсеры в JavaScript. Часть первая

Reading time 5 min
Views 30K
JavaScript *Programming *Functional Programming *
Рич Хикки, автор языка Clojure, недавно придумал новую концепцию — Трансдьюсеры. Их сразу добавили в Clojure, но сама идея универсальна и может быть воспроизведена в других языках.

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

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


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

Читать дальше →
Total votes 56: ↑52 and ↓4 +48
Comments 56

Трансдьюсеры в JavaScript. Часть вторая

Reading time 7 min
Views 13K
JavaScript *Programming *Functional Programming *
В первой части мы остановились на следующей спецификации: Трансдьюсер — это функция принимающая функцию 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)

Читать дальше →
Total votes 33: ↑31 and ↓2 +29
Comments 57

Атом — реализация на TypeScript

Reading time 13 min
Views 19K
JavaScript *Programming *
Здравствуйте, меня зовут Дмитрий Карловский и я… профессиональный велосипедист. За свою жизнь я перепробовал множество железных коней, но в конечном счёте остановился на самодельном. Не то чтобы мне очень нравилось работать напильником, тратя кучу свободного времени на изобретение колеса, но конечный результат, где каждая кочка не отдаётся болью в нижней половине туловища, того стоит. А теперь, когда вы знаете, что я затеял всё это не просто так, а чтобы сделать мир лучше, позвольте представить вам TypeScript/JavaScript модуль $jin.atom.

Краткое содержание предыдущей серии: простейшее приложение достигло критического уровня сложности, и, чтобы совладать с оной, была введена абстракция «атом», которая вобрала в себя всю рутину, позволив разработчику сконцентрироваться на описании инвариантов в функциональном стиле, не теряя связи с объектно ориентированной платформой. Вся теория и картинки там. Тут же будет куча практики, примеров кода и дампов консоли.
Читать дальше →
Total votes 22: ↑19 and ↓3 +16
Comments 58

Как изобрести велосипед и познакомиться с FRP

Reading time 10 min
Views 18K
Website development *JavaScript *Programming *
Недавно мне выпал шанс заняться веб-приложением для взаимодействия с интерактивной доской (!) для мобильных устройств (!!) на любом стеке технологий, как серверных, так и клиентских (!!!). На этапе прототипа задача представляла собой простейший графический редактор. Заказчик изъявил желание уметь рисовать ломаные каким-нибудь способом, круги, отрезки, произвольные кривые и добавлять текст. Все вроде бы просто, однако, наученный горьким опытом GoF, Фаулера и прочих апологетов всяческих паттернов, я сразу понял, что заказчик лукавит, и что уже через неделю-месяц после прототипа ему понадобится рисовать эллипсы, прямоугольники и кучи прочих ништяков. И все это точно надо будет делать разными способами. По крайней мере, для десктопа и мобил.

Собственно, можно все сделать в лоб (для прототипа-то), но выпали выходные, пауза в задачах текущего проекта, и я решил сделать все по-хорошему. И в первый же вечер — callback hell.

А потом…
Потому что на работе больше заниматься нечем

И вот так я изобрел велосипед...
Total votes 26: ↑20 and ↓6 +14
Comments 5

RSConf: Обзор и видеоматериалы фронтенд-конференции в Минске

Reading time 9 min
Views 9.5K
Website development *JavaScript *
Sandbox
image

The Rolling Scopes — минское сообщество фронтенд/javascript разработчиков. Мы занимаемся проведением митапов, воркшопов и Q&A сессий. А в этом году доросли до уровня, не побоюсь сказать этого слова, международной конференции. Наше 20-е мероприятие получилось помасштабнее остальных. В связи с этим непременно хочется поделиться деталями проведения, атмосферой и, конечно же, материалами.
Читать дальше →
Total votes 23: ↑21 and ↓2 +19
Comments 5

Грокаем* RxJava, часть первая: основы

Reading time 7 min
Views 176K
Development of mobile applications *Development for Android *
Translation
* от переводчика: я долго думал над тем, как перевести на русский язык глагол «to grok». С одной стороны, это слово переводится как «понять» или «осознать», а с другой стороны, при переводе романа Роберта Хайнлайна «Чужак в чужой стране» (в котором это слово впервые и появилось на свет), переводчики сделали из него русское «грокать». Роман я не читал, поэтому счёл, что есть у этого слова какие-то смысловые оттенки, которые русскими аналогами не передавались, а посему в своём переводе использовал ту же самую кальку с английского.

RxJava — это, сейчас, одна из самых горячих тем для обсуждения у Android-программистов. Единственная проблема состоит в том, что понять самые её основы, если вы не сталкивались ни с чем подобным, может быть довольно затруднительно. Функциональное реактивное программирование довольно сложно понять, если вы пришли из императивного мира, но, как только вы разберётесь с ним, вы поймёте, насколько же это круто!
Я постараюсь дать вам некое общее представление об RxJava. Задача этого цикла статей состоит не в том, чтобы объяснить всё вплоть до последней запятой (вряд ли я смог бы это сделать), но, скорее в том, чтобы заинтересовать вас RxJava, и тем, как она работает.
Читать дальше →
Total votes 27: ↑24 and ↓3 +21
Comments 31

Грокаем RxJava, часть вторая: Операторы

Reading time 6 min
Views 93K
Development of mobile applications *Development for Android *
Translation
В первой части мы с вами рассмотрели основные строительные блоки RxJava, а также познакомились с оператором map(). Я могу понять тех из вас, кто всё ещё не чувствует желания всё бросить и начать использовать этот фреймворк, так как пока что мы, условно выражаясь, рассмотрели лишь вершину айсберга. Но скоро всё переменится — большая часть всей мощи RxJava скрывается в её операторах, и я как раз подготовил для вас пример, по которому можно изучить некоторую их часть.
Читать дальше →
Total votes 17: ↑17 and ↓0 +17
Comments 8

Грокаем RxJava, часть третья: Реактивность с пользой

Reading time 5 min
Views 49K
Development of mobile applications *Development for Android *
Translation
В первой части мы прошлись по основам RxJava. Во второй части я показал вам потенциал операторов. Но, быть может, всего показанного мною всё ещё недостаточно для того, чтобы убедить вас. В таком случае я покажу вам ещё несколько полезностей RxJava, которые должны стать решающим аргументом в мою пользу.

Обработка ошибок


До настоящего момента мы полностью игнорировали такие методы Observable, как onComplete() и onError(). Данные методы вызываются в момент, когда Observable прекращает порождать новые данные — либо потому, что ему нечего больше порождать, либо потому, что произошла ошибка.
Самый первый наш Subscriber следил за onCompleted() и onError(). Давайте сделаем что-нибудь полезное в этих точках:

Observable.just("Hello, world!")
    .map(s -> potentialException(s))
    .map(s -> anotherPotentialException(s))
    .subscribe(new Subscriber<String>() {
        @Override
        public void onNext(String s) { System.out.println(s); }

        @Override
        public void onCompleted() { System.out.println("Completed!"); }

        @Override
        public void onError(Throwable e) { System.out.println("Ouch!"); }
    });

Читать дальше →
Total votes 15: ↑15 and ↓0 +15
Comments 2

Грокаем RxJava, часть четвертая: Реактивный Android

Reading time 6 min
Views 85K
Development of mobile applications *Development for Android *
Translation
В первой, второй и третьей частях я объяснил в общих чертах устройство RxJava. Вы можете подумать: «Прекрасно, но как всё это сделать полезным для меня, как для разработчика под Android?» В заключительной части статьи я приведу некоторую информацию, практичную именно для вас.

RxAndroid


RxAndroid — это расширение RxJava, написанное специально для Android, которое включает в себя специальные обвязки вокруг RxJava, делающие вашу жизнь проще.

Во-первых, здесь есть класс AndroidSchedulers, предоставляющий готовые планировщики для потоков, специфичных для Android. Нужно запустить код на UI потоке? Без проблем — воспользуйтесь AndroidSchedulers.mainThread():

retrofitService.getImage(url)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));
Читать дальше →
Total votes 16: ↑13 and ↓3 +10
Comments 14

Mobx — управление состоянием вашего приложения

Reading time 8 min
Views 122K
JavaScript *ReactJS *
Translation

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


Основная идея


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


MobX позволяет сделать управление состоянием вновь простым, вернувшись к корню проблемы: он делает невозможным инконсистентность состояния. Стратегия достижения этого довольно проста: убедится что, все что может быть вынуто из состояния, будет вынуто. Автоматически.

Читать дальше →
Total votes 9: ↑7 and ↓2 +5
Comments 40

$mol: reactive micromodular ui-framework

Reading time 28 min
Views 20K
Website development *CSS *JavaScript *Development of mobile applications *Node.JS *

Сколько нужно времени, чтобы просто вывести на экран большой список, используя современные фреймворки?


Список на 2000 строк ReactJS AngularJS Raw HTML SAPUI5 $mol
Появление списка 170 ms 420 ms 260 ms 1200 ms 50 ms
Обновление всех его данных 75 ms 75 ms 260 ms 1200 ms 10 ms

Напишем нехитрое приложение — личный список задач. Какие у него будут характеристики?


ToDoMVC ReactJS AngularJS PolymerJS VanillaJS $mol
Размер ( html + js + css + templates ) * gzip 322 KB 326 KB 56 KB 20 KB 23 KB
Время загрузки 1.4 s 1.5 s 1.0 s 1.7 s 0.7 s
Время создания и удаления 100 задач 1.3 s 1.7 s 1.4 s 1.6 s 0.5s

Небольшая головоломка: перед вами синхронный код, загружающий и обрабатывающий содержимое 4 файлов, но с сервера они грузятся параллельно. Как такое может быть?


Синхронная параллельная загрузка ресурсов


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


Читать дальше →
Total votes 54: ↑46 and ↓8 +38
Comments 150

$mol_atom: теория и практика реактивности

Reading time 15 min
Views 11K
JavaScript *Programming *
Recovery mode

Здравствуйте, меня зовут Дмитрий Карловский и я… состоятельный человек. У меня есть состояние на сервере, есть состояния в локальных хранилищах, есть состояние окна браузера, есть состояние доменной модели, есть состояние интерфейса. И всё это многообразие состояний нужно поддерживать синхронизированным. Если одно состояние как-то изменяется, то остальные связанные с ним состояния должны как можно скорее обновиться. Особую пикантность ситуации придаёт то, что синхронизация с сервером может занимать секунды, а блокировать пользовательский интерфейс можно лишь на доли секунд.


Состоятельный человек


Далее вы узнаете: как реактивность побеждает асинхронность, как императивная реактивность уживается с функциональной, как простые абстракции позволяют писать надёжный и быстрый код, а также как я однажды перешёл на идемпотентную сторону силы и всё заверте

Читать дальше →
Total votes 29: ↑22 and ↓7 +15
Comments 14

Factory Reset Protection: новый подход к защите персональных данных в Android

Reading time 4 min
Views 89K
М.Видео-Эльдорадо corporate blog Gadgets Smartphones
Шестая версия самой массовой и популярной операционной системы в мире Android от Google помимо ряда различных улучшений, которые подробно осветили при её анонсе и запуске, содержит как минимум одну интересную, а главное полезную опцию безопасности, о которой не рассказали широко.


Читать дальше →
Total votes 26: ↑26 and ↓0 +26
Comments 58

Mrr: тотальное FRP для Реакта

Reading time 18 min
Views 3.4K
JavaScript *
Tutorial
Mrr — функционально-реактивная библиотека для React'а (извиняюсь за мнимую тавтологию).

При слове «реактивность» обычно вспоминают Rx.js, как эталонный образец FRP. Однако серия последних статей на эту тему на Хабре([1], [2], [3]) показала громоздкость решений на Rx, которые на несложных примерах проигрывали в ясности и простоте почти любому другому подходу. Rx велик и могуч, и прекрасно подходит для решения проблем, в которых абстракция потока напрашивается сама собой (на практике это преимущественно координация асинхронных задач). Но стали бы вы писать, к примеру, простую синхронную валидацию формы на Rx? Сэкономил бы он ваше время, по сравнению с обычными императивными подходами?

mrr — это попытка доказать, что ФРП может быть удобным и эффективным решением не только в специфических «потоковых» проблемах, но и в самых обычных рутинных задачах фронтенда.
Читать дальше →
Total votes 9: ↑7 and ↓2 +5
Comments 15
1