?

Log in

No account? Create an account
светлое будущее
Mike Potanin potan
Previous Entry Share Next Entry
Паттерн Model-Update-View и зависимые типы
Написал статью на Хабре о том, чего нет в Elm.
Кто не может комментировать там, могут комментировать здесь.

> чего нет в Elm

Чего только нет в Elm! ;-)

На самом деле, крайне интересная статья, большое спасибо!

Со своей стороны, могу предложить такую идею: можно немного переосмыслить основной внешний цикл (update -> view -> update -> …), перенеся его, собственно, в функцию view, которая станет рекурсивной.

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

Вот, например, как это может выглядеть на Rust: https://gist.github.com/swizard0/9ad5175d31f60646315ec77674a7d4c8

Спасибо, на Rust у меня сходу не вышло. Но я старался все-таки view от модели отделить, так как у меня всегда с разработкой view получается плохо и я стараюсь ее кому-нибудь сплавить :-).

Кстати, а на Rust можно использовать Servo как view и дальше делать UI в стиле MUV?

И еще - Rust умеет гарантировать TCO? Здесь легко ошибиться и передать model по ссылке, тогда Rust станет удалять ее после вызова view, но ни чего не скажет про то, что вызов перестал быть хвостовым.

Edited at 2017-11-21 07:17 am (UTC)

> Но я старался все-таки view от модели отделить

Формально он там отделён, разница с оригинальной архитектурой только в том, что вместо возврата сообщения происходит рекурсивный вызов, куда это сообщение передаётся аргументом (типа такой continuation).

Другое дело, я тут сообразил, что в этом месте у меня возникает место для потенциальных ошибок другого рода: можно же забыть сделать этот рекурсивный вызов, и тем самым вообще завершить цикл :)

Надо будет подумать, наверняка должен быть способ заставить компилятор отследить этот момент. Может, что-то типа возврата значения специального типа, которое нигде, кроме как в view создать нельзя.

> Кстати, а на Rust можно использовать Servo как view и дальше делать UI в стиле MUV?

Можно, наверно, просто это как-то, тяжеловесно, что ли :) Если интересно, можешь поискать на crates.io по ключевому слову "elm", там есть какое-то количество экспериментов по реализации MUV, например: https://crates.io/crates/elmesque или https://crates.io/crates/relm

> И еще - Rust умеет гарантировать TCO? Здесь легко ошибиться и передать model по ссылке, тогда Rust станет удалять ее после вызова view, но ни чего не скажет про то, что вызов перестал быть хвостовым.

По-моему, сам не умеет, он в этом плане всецело полагается на llvm (который емнип умеет). А ошибиться в передаче model нельзя — там же в сигнатуре функции указано, что ему нужно передать владение :) Это на компиляции будет.

Возможноть из view завершить цикл - может даже плюс. Конечно, лучше если бы это было явно.

relm выглядит вполне рабочим, надо попробовать. Спасибо, я не догадался так искать :-).

Можно ошибиться в сигнатуре, тогда все будет работать, но без TCO.