Hacker News new | ask | show | jobs
by imaok 4025 days ago
The biggest difference in thinking comes from the concept of signals. Initially when you hear that a signal is a value that changes over time it doesn't seem all that different from setting the state on an object. But actually a signal is more like an array in that it's also a collection of values except it's a collection of values over time. And crucially, like an array, a signal can be mapped over. If you look at the last line you see that 'main' is a signal of Elements, which we can assume is some type that elm knows how to display in the browser.

So a single instance of Element can be thought of as the browser's displayed state at a single point in time, in this case a single frame of the ship's movement animation. Each subsequent Element in the signal can be thought of as a transition from one browser state to the next, or from one animation frame to the next.

Now the key is that each Element in the Element signal is being mapped 1 to 1 with a Ship in the Ship signal. (The Ship signal is the return value of 'Signal.foldp update initShip inputSignal') In fact the whole application can be thought of as a transformation on an initial Ship and a signal of keyboard inputs, to producing a signal of Elements.

So in building this app the thought process might be that I first create an initial Ship and a signal of keyboard inputs to start. I want my app to update at 30fps, so I create a signal that samples the keyboard inputs signal at this interval. Now from this input signal I want to produce a signal of updated Ships. From the signal of Ships I want to produce a signal of Elements.

Finally you can see everything come together at the end, and it is quite descriptive. You want a signal of Elements. What is a signal of Elements? It is a mapping of a signal of Ships over the show function. What is a signal of Ships? It is a signal of inputs foldp'd over an update function (which gets passed the input and the most recent Ship). What is an input signal? It is a sampling of the user's keyboard inputs at a 30fps interval. Etc.

So we end up with descriptive functional code. There are no statements here, no loops, and no mutation, which means that we don't need to coordinate the order of execution with changes in the state of objects, which is a huge step forward in reducing the complexity of a program.