Tools for developing Elm programs! :wrench:
Tools for developing Elm programs!
The overarching goal is to close the loop between writing Elm code and interacting with it. This concretely means:
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.
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.
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:
These devtools run in sessions. A session is essentially made up of:
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.
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:
Msg
was given another constructor, called Reset
which updates Reset -> 0
, the value of state
is still 1
. Append-only changes are always compatible. Great.Msg
had Decrement
removed (or changed), one of three strategies (of your choice) could be used:
Decrement
has no meaning in the program anymore. The value of state
is now 0
, and we've accomplished nothing. This is how most web-app development works.Decrement
out of the list and update accordingly. The value of state
is now 2
. This works better or worse depending on the coupling between the updates your messages perform. If you remove LogIn
and expect ViewAccount
to work, you will be dissapointed.Decrement
and update using those. The value of state
is now 1
. This is really great, as it captures the remaining valid sequence of updates the application could do. If LogIn
goes away, you'll never try to ViewAccount
.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 tweak update
until it works as intended. You can tweak view
and subscriptions
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.