opvasger / Devtools
Programming Languages
Projects that are alternatives of or similar to Devtools
Elm DevTools
Tools for developing Elm programs!
Goals
The overarching goal is to close the loop between writing Elm code and interacting with it. This concretely means:
- Code changes should be reflected immediately in a running instance of its application.
- Code changes should only break application-state if necessary, and if enabled, only partially.
- Application-states should be effortless to inspect, navigate, persist and share.
- Guidance from the compiler should be right in front of you when you make mistakes.
- The boilerplate necessary to enable the first four goals should be minimal, and if needed be, incremental.
I strongly believe that the optimal design and implementation of these goals will transform how we build our applications. Going through the loop of compiling code, reloading browser windows and getting the application into the right state costs seconds, but those seconds are spent at such a frequency that writing interactive applications is incredibly time-consuming. I hope it doesn't have to be.
Design
These devtools are based on the Elm architecture. Since programs are constructed using a few simple functions, they can be embedded and controlled, which also sets some limits for what these devtools can do.
Automatic Message Replay
Any previous state of an application can be recomputed using the initial state and a list of messages folded by an update-function. These state-transitions happen independently of their environment - no commands are sent during replay, only the state changes. This is very useful to:
- Stop time to look at what happened.
- Go to a previous point in time to try something else.
- Reload without losing the state of your application.
- Reload with code changes but only partial (or no) loss of application state.
Sessions
These devtools run in sessions. A session is essentially made up of:
- devtools settings and state.
- all messages that ever updated the debugged applications state.
Sessions keep track of what your doing during development. They persist through browser-reloads, code-changes, can be downloaded, sent, opened by collaborators, and submitted as bug-reports.
Support for Code-Changes
To reliably support code-changes in sessions, it is essential that interactions are recorded rather than states. Interactions are modeled in Elm applications with a single type, usually called Msg
. Let's do an example:
type Msg = Increment | Decrement
update msg count = case msg of
Increment -> count + 1
Decrement -> count - 1
state = List.foldl update 0 [ Increment, Decrement, Increment ]
If you run this example, the value of state
will be 1
.
Refactor this into an application, and devtools would deal with changes to this code in different ways:
- If
Msg
was given another constructor, calledReset
which updatesReset -> 0
, the value ofstate
is still1
. Append-only changes are always compatible. Great. - If
Msg
hadDecrement
removed (or changed), one of three strategies (of your choice) could be used:- Restart the application, as
Decrement
has no meaning in the program anymore. The value ofstate
is now0
, and we've accomplished nothing. This is how most web-app development works. - Filter
Decrement
out of the list and update accordingly. The value ofstate
is now2
. This works better or worse depending on the coupling between the updates your messages perform. If you removeLogIn
and expectViewAccount
to work, you will be dissapointed. - Take messages until you reach the first
Decrement
and update using those. The value ofstate
is now1
. This is really great, as it captures the remaining valid sequence of updates the application could do. IfLogIn
goes away, you'll never try toViewAccount
.
- Restart the application, as
- If
update
is changed, any sequence of messages will still be (generally) valid.Increment
might do a+ 2
instead, but messages still capture your interactions, so you can tweakupdate
until it works as intended. You can tweakview
andsubscriptions
in the same way.
By recording interactions rather than state, Elm applications can be written while running, and you will only ever have impared (but predictable) message-replay when you modify the definition of messages.