Реализация снимка в FRP

Я внедряю FRP-фреймворк в Scala и, похоже, столкнулся с проблемой. Руководствуясь некоторыми размышлениями, этот вопрос я решил ограничить общедоступным интерфейсом моей платформы, чтобы поведение можно было оценить только в "настоящем", то есть:

behaviour.at(now) 

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

val slider = Stepper(0, sliderChangeEvent) 

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

У меня возникли проблемы со спецификацией для операции "моментальный снимок" в поведении с учетом этого ограничения. Моя проблема лучше всего объясняется на примере (с использованием ползунка, упомянутого выше):

val event = mouseB // an event that occurs when the mouse is pressed 
val sampler = slider.snapshot(event) 
val stepper = Stepper(0, sampler) 

Моя проблема здесь заключается в том, что если при выполнении этого кода произошло событие "mouseB", то текущее значение "stepper" будет последним "образцом" "ползунка" (значение во время последнего вхождения). Если время последнего вхождения прошло, то мы в итоге будем оценивать "ползунок", используя прошедшее время, которое нарушает установленное выше правило (и ваше исходное предположение). Я вижу несколько способов решить эту проблему:

  1. Мы "записываем" прошлое (сохраняем все прошлые события в событии), позволяя оценивать поведение с прошедшими временами (используя неограниченный объем памяти)
  2. Мы модифицируем "снимок", чтобы принять аргумент времени ("образец после этого времени") и принудительно установить, что это время>= сейчас
  3. В более дурацком движении мы могли бы как-то ограничить создание объектов FRP первоначальной настройкой программы и начинать обрабатывать события / ввод только после завершения этой настройки.

Я также мог бы просто не реализовывать "sample" или удалять "stepper" / "switcher" (но я действительно не хочу делать ни одну из этих вещей). У кого-нибудь есть мысли по этому поводу? Я что-то здесь неправильно понял?

3 ответа

Решение

О, я понимаю, что ты имеешь в виду сейчас.

Я полагаю, что ваше ограничение "Вы можете выбирать только сейчас" недостаточно жесткое. Это должно быть немного сильнее, чтобы не заглядывать в прошлое. Поскольку вы используете экологическую концепцию nowЯ бы определил функции построения поведения в терминах этого (до тех пор, пока now не может продвинуться простым исполнением определений, которое, согласно моему последнему ответу, стало бы грязным). Например:

Stepper(i,e) это поведение со значением i в промежутке [now,e1] (где e1 время первого появления e после now), а также значение самого последнего появления e после этого.

С этой семантикой ваш прогноз о значении stepper то, что привело вас в эту головоломку, демонтировано, и степпер теперь будет иметь значение 0. Я не знаю, желательна ли вам эта семантика, но она кажется мне достаточно естественной.

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

Чисто функциональный код не любит знать, что он исполняется. Функциональные приемы являются лучшими в чистом виде, так что не имеет значения, в каком коде заказа выполняется. Выход из этой дилеммы - сделать вид, что каждое изменение произошло в одном чувствительном (внутреннем, вероятно) фрагменте императивного кода; притвориться, что любые функциональные объявления в структуре FRP происходят за 0 раз, поэтому невозможно что-то изменить во время их объявления.

Никто не должен спать или делать что-то чувствительное ко времени в разделе кода, который объявляет поведение и вещи. По сути, код, который работает с объектами FRP, должен быть чистым, тогда у вас нет проблем.

Это не обязательно исключает запуск его в нескольких потоках, но для поддержки этого вам может понадобиться реорганизовать ваши внутренние представления. Добро пожаловать в мир внедрения библиотеки FRP - я подозреваю, что ваше внутреннее представительство будет колебаться много раз в течение этого процесса.:-)

Я запутался из-за твоего замешательства. Я вижу, что Stepper будет "устанавливать" поведение на новое значение всякий раз, когда происходит событие. Итак, что происходит, это следующее:

Момент, в который произошло событие mouseB происходит, значение slider поведение будет прочитано (snapshot). Это значение будет "установлено" в поведении stepper,

Таким образом, это правда, что Stepper будет "запоминать" ценности из прошлого; Дело в том, что он запоминает только последнюю ценность из прошлого, а не все.

Семантически лучше всего моделировать Stepper как функция, которую предлагает Луки.

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