Комментарии 17
ClojureScript сам по себе ничего не даёт для FRP, на нём просто элегантно все можно реализовать.
Для наведения красотулек бекон тоже очень помогает, там тоже бывает много связей.
А насколько сильно страдает производительность? Единицы, десятки процентов?
Пробовал подобное (observable — переменные) навешивать на таблицу данных. Если 10-100 значений — нормально, если в боевом режиме (там до 1000 может доходить) — всё, браузер складывается…
Подозреваю что 10-100 asEventStream не особо напрягают систему?
В официальном FAQ пишут что производительность толком не тестировали, но с другой стороны никто не жаловался.

Там есть какие-то оптимизации. Например, если я правильно понял, если никто не слушает поток то, сам поток не будет слушать свой источник событий; или если поток получен с помощью map (someStream.map(someFunction)), но у него нет подписчиков, то и someFunction выполняться не будет. Как-то так.
Опять же от подхода зависит. Я профилировал в Firebug, и есть три основные ситуации, где важно учитывать потери в производительности:
1) Много разнородных объектов, создающих много разнородных эвентов, которые между собой могут быть связанны, а могут быть и нет. В таком случае приходится часто пользоваться методами scan(), combine() и filter(), которые могут по факту обрубать обработку событий потока, где-то в конце цепочки, и тем самым уменьшать производительность тем, что в stream.map(b).map(c).filter(someFunction).toProperty(d).scan(e,anotherFunction) до scan могут доходить редкие события, а все функции b,c,someFunction выполнятся все равно будут.
2) Большое количество однородных объектов, создающих разнородные события, с предсказуемой реакцией, например те же таблицы данных (например, если эмулировать некоторый функционал Excel в браузере), то тут потери небольшие т.к. почти все эвенты надо слушать и на них надо реагировать.
3) Большое количество однородных объектов, создающих одни и те же эвенты. Так как события одни и те же, условия одни и те же, выходит, что слушать надо все события, а реагировать в зависимости от объекта т.к их много, следовательно вычисления нужного поведения занимают много времени, а когда еще и событий много, то тут могут быть серьезные потери в скорости исполнения.

Самая годная практика заранее знать, что и как лучше слушать. Можно приводить какие-то потоки к property и слушать их, когда в этом возникает необходимость. Это, конечно, немного мутировавший вариант FRP, и с декларативным стилем не сочетается, но если действительно нужна оптимизация, то лучше уж так, наверноею
Чёта фразу прочитал как: «Самая годная практика заранее знать, что и как лучше сделать.»
И это пять! :)
Пробовал разные варианты. И виртуальная, и частично отрисованная, и полностью.
Но бекон попробую. Мало ли, вдруг в моём случае хорошо всё будет :)
просто интересно
1. сколько человек переписало по свойму код из примера?
2. что использовали при этом?

может сделать что-то типа todomvc.com/ только для сокобана :)
Хорошая статья, яркий пример! Но возник вопрос: все эти функции isEmpty, isGoal, nextCell, isMine — они не чистые, они читают глобальный state игры, получается как-то не в функциональном стиле. Это нормально или лучше сделать как-то, чтобы state игры (состояние карты, координаты игрока) хранились внутри потока?
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.