0.3.x of the Elm compiler has two major goals:
- Make Elm more practical.
- Make it easy for anyone to help Elm grow.
Ok, now that I’ve pestered you about sharing your code and experiences with the internet (do it!), let’s get to the details of the release.
I have created a couple example programs that use the JS Event Interface (JSEI) so you can see it in action (source). The three most exciting examples are probably:
FrameRate/(source,result) which demonstrates a basic “game” that keeps a steady frame rate. If the users browser cannot handle the desired frame rate, the game will update as quickly as possible. For users that can handle the frame rate, it will update only as frequently as necessary to maintain the desired frame rate.
Maps/(source,result) which demonstrates basic integration with OpenStreetMap.
Form/(source,result) which is a simple form with client-side validation. This example needs the JSEI to redirect to a different page. I have gotten a couple questions about how to go about doing this, so now you know!
Now that you’ve seen the JSEI in action, lets talk about details.
foreign export jsevent "eventName" signal :: Signal JSString
This code snippet takes an Elm signal
signal and broadcasts all of its values as an event named
"eventName". Note that the type of the exported value must be a
foreign import jsevent "eventName" (castIntToJSNumber 0) signal :: Signal JSNumber
Notice that importing has one additional value: a default value. Elm was designed so that every signal is always defined. This default value will be the initial value of the imported signal. As soon as events come in, the signal will take their value. One thing to note is that — right now — these foreign definitions must come between any normal module imports and the beginning of your code.
The actual event protocol is fairly basic. An exported signals will produce some event
outEvent. The exported value is accessible via
outEvent.value. Similarly, when Elm receives an imported event
inEvent, it will look for the imported value at
inEvent.value. These points are probably better understood by looking through the examples linked above.
Built-in Event Listeners
elm_redirect. With these listeners, you can make some common imperative actions without having to worry about writing the JS yourself. For example:
foreign export jsevent "elm_log" message :: Signal JSString
will log the current value of the
message signal in the developer console of your browser. The user does not need to write any JS.
elm_titlework much the same way, except that they both ignore empty strings.
A signal always has a value, but the value changes discretely when events occur in the world. Elm’s new signal filtering functions allow you to block events, making the signal retain its previous value. This was not previously possible in Elm. The new filter functions are:
keepIf :: (a -> Bool) -> a -> Signal a -> Signal a dropIf :: (a -> Bool) -> a -> Signal a -> Signal a keepWhen :: Signal Bool -> a -> Signal a -> Signal a dropWhen :: Signal Bool -> a -> Signal a -> Signal a dropRepeats :: Signal a -> Signal a sampleOn :: Signal a -> Signal b -> Signal b
Notice that many of these functions require a default value. The danger of filtering is that no events ever make it through (
keepIf (\_ -> False)). And as mentioned above, an undefined signal is a bad signal. For more detailed documentation see this. I have also created a couple examples of these functions in action: sampleOn, keepIf, and dropRepeats.
Elm now uses a more compact format for strings. This should make strings 10-12 times more space efficient than in previous releases. Anecdotal evidence: Elm’s home page is now 70% of its previous size. Thank you to Conrad Parker for suggesting this simple and clever space saving technique! There are two more signal values as of this release (docs and docs). They don’t really fall into the category of filtering, but these dovetail with the filtering functions quite nicely.
count :: Signal a -> Signal Int clicks :: Signal ()
I also added one new function to
last :: [a] -> a
And of course, a couple of miscellaneous bugs have been fixed. I hope I found them before you did!
I hope you will give Elm a try! Follow these instructions to if you installing for the first time or upgrade with
cabal update; cabal install elm.