-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Store messages instead of model
?
#19
Comments
Recently I've been discussing this with @opvasger who is exploring a pure-Elm solution that relies on the technique you described. And I discussed it with @evancz during the 0.19 alpha because the introduction of That idea has a lot going for it:
But there are also some downsides:
What I mean by "jarring app state" in (1) and (2) is that when you reload the code, you expect that the visual state of the app remains the same with the exception of intentional changes that you made to how things are rendered. But imagine that you have a counter app and you clicked the plus button 3 times. Now you rename the increment msg in your code from The Elm debugger handles problems 1 and 2 by being privvy to the types used by the program that emitted the messages and refusing to load if the types have changed. It can afford to be very conservative in these cases because there is some expectation that if you were to load one of these history files, you would be loading into (more-or-less) the same app version. But in the case of hot module reloading, development is occurring at a rapid pace and things are changing frequently. So at a minimum, we would want a way to detect that the Problem (3) is fairly straight-forward: if you have an app that generates messages at high frequency (e.g. via an animation timer or mouse-move events), you can quickly collect 10s of thousands of messages. In my brief testing, this didn't appear to be a problem, but it was on my mind. At the end of the day, I rolled-back the change and stuck with fluxxu's original implementation. It seemed more important to get it working with 0.19 than to change the way that it behaves. Ultimately, I think the right thing to do is to switch to
|
Hello ☀️ I'm experimenting here if you want to take a look. There's an example to quickly get started. my local version of the repo is running a Mario-app I implemented to iterate on, as it updates on animation-frames. I have a lot of thoughts about using this kind of tool for a website/utility style application, but I hope to find a nicer way to support apps that update a lot more. I'll add docs to the repo with my progress so it will be easy to follow along. Any kind of help would be much appreciated! I also want to gathering information about how other languages/tools approach this and hopefully get inspired! I'll start with your gist, @rtfeldman I plan to experiment with:
Thanks again for your guidance ⭐ @klazuka |
Totally agree with that!
I think that makes sense when tweaking visual elements, but I also think there are use cases where expectations differ! I think in general we're on the same page with message replay being a good idea to at least try, but I came to a somewhat surprising conclusion when thinking it through, so I'd like to walk through how I got to that conclusion if you'll bear with me. A direct use case for message replayLet's say I'm working on a lengthy form, and I'm trying it out. I fill it out and hit submit, and I get a validation error. The validation error is a bug though; it was actually supposed to submit successfully. So I go into
TradeoffsI can see some obvious arguments for (1) and (3). The upside of (1) is that it saves me time. I don't have to fill out the form again. On the other hand, as @klazuka noted above, it can mean I end up seeing visually jarring changes. The upside of (3) is that it reduces the incidence of impossible states being rendered, at the cost of developers spending more time retracing steps to get back into the desired state. I don't see a clear argument for why (2) would be better than either (1) or (3). You don't get the time savings of the revised The case for message replayOne of the reasons I lean towards (1) over (3) because "hot loading will never render impossible states" is not something anyone can rely on anyway. Even if I only ever make changes to Since it's never safe for people to assume "if I see it on my screen, I'll be able to refresh the page and get back to it again" in general with hot loading, it seems better to make sure people are aware of this possibility than to nurture a false sense of security about it. NamingI think calling this feature something other than "hot loading" could help people understand what it does. For example, I think it's very clear what a feature like this named "Automatic Message Replay" does: when you make a change, it automatically replays the messages. I think if I told someone "automatic message replay is enabled out-the-box" as opposed to "hot reloading is enabled out-the-box" they would more fully understand what that meant, including the limitations, based on the name alone—literally no matter which of these design directions the "hot loading" approach went with. Summary
|
Thank you for taking the time to write this up. Thinking through the edge cases is complicated—it definitely makes my head asplode at times. I agree on all your points, namely:
I'm inclined to let @opvasger run with his effort to unify the debugger with live reload. The main downside of his pure Elm approach is that you have to write Json encoders for all your messages, which is not great for big apps. Retrofitting this library to use message playback would require a couple of things:
One thought I had for (2) was to require that the app be compiled in I am reluctant to take on any big, new projects. But if someone were inclined to make this work, I think the best thing would be to work on the Elm debugger itself so that it could vend type metadata to projects like this and @opvasger's elm-dev-tools. And make sure that there is not so much of a performance tax when compiling with |
Currently if I change
init
or my initial model, those changes will not get hot-loaded becausehmr.js
remembers the last model state.I made a proof of concept back in 0.18 of doing hot loading by storing
init
and the list of messages instead ofmodel
: https://gist.github.com/rtfeldman/f259128af7fea653876c34cca033ae68When you change your code, including
init
or the initialmodel
, it would replay the messages on top of the new code. This would also continue to work for any of the existing use cases, because the current model state can be derived by replaying messages on top of the initialmodel
.Thoughts?
The text was updated successfully, but these errors were encountered: