LINUX.ORG.RU

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


0

4

Прочитал про сабж и вот этот пример:

К примеру, в императивном программировании присваивание a := b + c будет означать, что переменной a будет присвоен результат выполнения операции b + c, используя текущие (на момент вычисления) значения переменных. Позже значения переменных b и c могут быть изменены без какого-либо влияния на значение переменной a. В реактивном же программировании значение a будет автоматически пересчитано, основываясь на новых значениях.

натолкнул на мысль. А ведь это подмена понятий. Тут a - это же просто фунция! Что-то вроде

b=1
c=1
a=function(){return b+c}
a() -->2
b=2
a() -->3
[update]

Даже вот так наглядней будет, чтобы не отвлекаться на присваивания:

b=function(){return 1}
c=function(){return 1}
a=function(){return b()+c()}
a() -->2
b=function(){return 2}
a() -->3

[/update]

ведь это же обычное императивное программирование. Дело в синтаксисе? То что мы обращаемся к a не a(), а просто: a? Это важно, дооо.

Тем более странно, что там снизу, на вики, они плетут еще что-то пр фп-реактивное программирование. Да современное фп, со своей анальной фиксацией на замыканиях и иммутабельности, это 100% АНТИреактивное программирование. Они наоборот замораживают состояние, какая там реактивность может быть? Что это за идиотизм такой? Как разобраться в этих дебрях, когда кругом идиотизм зашкаливает:)?

PS Да, и кстати, эта парадигма нам как-бы, в очередной раз, намекает, что никакой разницы между функциями и данными нет, BTW.



Последнее исправление: anonimous (всего исправлений: 3)

Реактивное программирование позволяет распространять изменения. Сравнить можно с формулами в excel'е(и аналогах), например. Т.е. меняем значение ячеек и все формулы сразу считай пересчитаны. FRP - это единственное, что позволяется нормально и красиво описывать, например, GUI. Без всяких костылей и уродств.

anonymous
()

А ведь это подмена понятий. Тут a - это же просто фунция!

Угадал автора после этих строк.

nanoolinux ★★★★
()
Ответ на: комментарий от anonymous

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

anonimous
() автор топика

Позже значения переменных b и c могут быть изменены без какого-либо влияния на значение переменной a

a() -->2
b=2
a() -->3

ЯННП, но тут что-то явно не так.

anonymous
()
Ответ на: комментарий от anonymous

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

anonimous
() автор топика
Ответ на: комментарий от anonymous

Скопипастил просто не полностью, сейчас добил в цитату, чтобы понятней было, о чем речь.

anonimous
() автор топика

Подумать только, ты обнаружил что в js тоже есть замыкания и на нём тоже можно писать в fp-стиле.

KblCb ★★★★★
()
Ответ на: комментарий от anonimous

Если обратить внимание на смысл слова «реактивное», то станет ясно, что важна не формула пересчета, а момент передачи управления в процедуру-реакцию. b=2 в твоем случае не вызывает никаких цепных реакций, так что активные представления вынуждены будут поллить свои данные, что сводит на нет весь смысл реактивности (не говоря об идиотизме полных пересчетов по любому дата-событию).

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от arturpub

И у тебя «а» почему-то функция, а «б» переменная. Приведи хоть к одному виду, что-ли, перед дальнейшими раздумьями.

Я привел во втором примере. А вообще, с точи зрения семантики, не вижу, по-прежнему, никакой разницы. Функция точно также пересчитывает значения. Никакой друой реализации, кроме постоянных динамических перерасчетов я не вижу. Возможно там оптимизаци какие-то под капотом и есть, но по-сути — то же самое. Это динамика.

anonimous
() автор топика
Ответ на: комментарий от arturpub

b=2 в твоем случае не вызывает никаких цепных реакций

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

anonimous
() автор топика
Ответ на: комментарий от anonimous

Представь таблицу из 100500 строк одного вида, например — колво, цена, сумма. В общем виде ты не знаешь, как связаны все 301500 значений, знаешь только, что при любом изменении должны быть обновлены x% из них. В твоем случае, при изменении колва в одной строке, таблица вынуждена будет перезапросить все значения, а в реактивном случае цепь остановится сразу после пересчета суммы и таблице нужно обновить всего одну ячейку. Кроме того, расчеты элементов могут быть нетривиальны, и тогда тормоза обеспечены.

Кстати, вот тебе еще задачка: колво-цена-сумма-ставкандс-ндс. Если мы меняем ндс, то должна пересчитаться сумма (и следом цена (или таки колво?)), или же ставкандс? Предваряя ответы, скажу, что рассчитать одно и то же можно по-разному, если заходить с разных сторон — это естественная часть человек-ориентированных расчетов.

И еще у тебя концептуальная проблема, что заменяя b другой функцией, ты не перебиндиваешь на нее все прошлые замыкания, а работать, опираясь только на глобальный контекст — как минимум негигиенично.

arturpub ★★
()
Ответ на: комментарий от anonimous

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

колво = сумма / цена
цена = сумма / колво
сумма = цена х колво

Когда остановится расчет суммы в любом яп?

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от arturpub

И еще у тебя концептуальная проблема, что заменяя b другой функцией, ты не перебиндиваешь на нее все прошлые замыкания, а работать, опираясь только на глобальный контекст — как минимум негигиенично.

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

anonimous
() автор топика
Ответ на: комментарий от anonimous

Я и не настаиваю, главная проблема была абзацем выше.

arturpub ★★
()

ведь это же обычное императивное программирование

Осиль уже ассемблер, сможешь написать еще пару сотен «разоблачений» на ЛОР, я гарантирую это.

Kuzy ★★★
()

У тебя тут получается просто ленивое вычисление значения. Реактивное программирование не лениво, как раз на оборот. В твоем примере в реактивном программировании при изменении b значение a должно сразу начать вычисляться. Через какое-то время a поменяет свое значение. Профит в том, что значение a всегда доступно на чтение (хотя может быть и не определенным)

dizza ★★★★★
()

Они наоборот замораживают состояние, какая там реактивность может быть? Что это за идиотизм такой? Как разобраться в этих дебрях, когда кругом идиотизм зашкаливает:)?

реактивность

состояние

b=function(){return 1}
c=function(){return 1}
a=function(){return b()+c()}
a() -->2
b=function(){return 2}
a() -->3

Если тебе действительно интересно ФРП ли это - перепиши этот код на Elm (пока не закончишь писать не открывай ЛОР, тебе же будет лучше).

Kuzy ★★★
()
Ответ на: комментарий от anonimous

Можно использовать реактивное программирование в императивном языке, если ты спрашиваешь об этом. В js активно используют, например.

anonymous
()
Ответ на: комментарий от anonimous

Вычисление a у тебя блокирующая операция может быть, из ui потока дергать нельзя. Можно вынести это вычисление в отдельный поток. Вуаля, получили стандартную лениво-асинхронную лапшу. Реактивное программирование просто более удачная абстракция, которая позволяет описать байндинг компонентов декларативно. Да, задачу можно решить многими способами, что тут удивительного?

dizza ★★★★★
()
Ответ на: комментарий от dizza

Реактивное программирование не лениво, как раз на оборот

Наоборот быть не может в принципе. Если что-то изменено, а мы н знаем что, нет иного способа, как заново пересчитать.

anonimous
() автор топика
Ответ на: комментарий от anonimous

Причем здесь мы? Пересчитает за нас frp-библиотека. Там обычно можно не тупо пропогейтить, но и тротлить изменения, что бы не заспамить систему пересчетами.

dizza ★★★★★
()
Ответ на: комментарий от dizza

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

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

Если тебе действительно интересно ФРП ли это

Нет, мне не интересно, ФПР ли это, потому как, очевидно, что это не ФПР, а ПР. А вот что такое ФПР, и как оно может быть вообще, существовать, вот это интересно, потому как ящетаю, что это в принципе невозможно.

anonimous
() автор топика
Ответ на: комментарий от anonimous

А вот что такое ФПР, и как оно может быть вообще, существовать, вот это интересно, потому как ящетаю, что это в принципе невозможно.

Ну так смотри Elm. Он декларативный.

Kuzy ★★★
()
Ответ на: комментарий от dizza

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

anonimous
() автор топика
Ответ на: комментарий от anonimous

Не сахар, а абстракции, которые и есть концептуальный уровень. Как там подноготная устроена ниразу уже не концептуальный уровень, наоборот, это уровень реализации. А в самом низу реализациия у всего одинаковая - императивщина, архитектура фон-неймана и так далее. Как именно компелятор пересчитает вопрос тоже интересный, но это уже другой вопрос.

dizza ★★★★★
()
Последнее исправление: dizza (всего исправлений: 1)
Ответ на: комментарий от dizza

В твоем примере в реактивном программировании при изменении b значение a должно сразу начать вычисляться. Через какое-то время a поменяет свое значение. Профит в том, что значение a всегда доступно на чтение (хотя может быть и не определенным)

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

anonimous
() автор топика
Ответ на: комментарий от anonimous

И, кстати, я не считаю, что декларативность связана с ФП.

ФП для тебя это поддержка функций высших порядков? Тогда я не понял что тебе не понятно. Да ФРП можно сделать на js (вот например: https://github.com/baconjs/bacon.js/tree/master).

ведь это же обычное императивное программирование

Зачем ты тогда писал это?

Может ли быть функциональный язык императивным - да может, еще что?

Kuzy ★★★
()
Ответ на: комментарий от dizza

но это уже другой вопрос

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

anonimous
() автор топика
Ответ на: комментарий от anonimous

Связана на прямую. Просто определение декларативщины обычно дается стремное, типа решение за тебя придумывается, ты лишь описываешь задачу. На самом деле декларативщина это когда ты не описываешь ручками control flow, это за тебя делает среда исполнения в зависимости от входных данных. Ну и да, это более высокий уровень, более выразительный, но ни разу не избавляет от потребности в понимании какой получается flow на выходе. Например знание sql без понимания того, какой получается план запросов ведет к печальным результатам. Но все равно это проще - пишешь декларативно, профилируешь, меняешь что бы лучший план получился. Получается что ты пишешь императивный код не голыми руками, а автоматизированно.

dizza ★★★★★
()
Ответ на: комментарий от anonimous

Про уровень реализации ответил выше.

dizza ★★★★★
()
Ответ на: комментарий от Kuzy

ФП для тебя это поддержка функций высших порядков?

Нет. В современном понимании это иммутабельность и замыкания, и все что с этим связано — классы, экземпляры, карринг и пр. Именно в таком подходе реактивность невозможна. ФВП тут боком вообще.

Да ФРП можно сделать на js

s/ФРП/РП

s/js/любой императивный ЯП

anonimous
() автор топика
Ответ на: комментарий от Kuzy

Иммутабельность тоже никак не связана с декларативностью. Декларативность — это всего лишь стиль.

anonimous
() автор топика
Ответ на: комментарий от Kuzy

Банальный пример

(sum (fact 5) (fact 6))
тут факториал может внутри реализован с присваиваниями, но запись эта от этого менее декларативной не становиться. Просто я отношусь к факториалам как к числам, как к данным, а не как к вычислениям.

anonimous
() автор топика
Ответ на: комментарий от anonimous

факториал может внутри реализован с присваиваниями

Естественно я имел ввиду полностью декларативный (без императивных частей).

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

ты просил

Покажешь декларативный язык без иммутабельности?

Я показал. Вот это:

Естественно я имел ввиду полностью декларативный (без императивных частей).

Я вообще не понял. Есть ли декларативные ЯП без иммутабельности, или что? Я показал, что муттабельность не мешает ЯП быть декларативным, поэтому ФП (в понимании haskell-like) с декларативностью не связано.

anonimous
() автор топика
Ответ на: комментарий от Kuzy

Не знаю. Я с трудом себе представляю такое. И тем не менее, я изначально утверждал, что ФП с декларативностью напрямую не связано. По этому поводу есть возражения?

anonimous
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.