@@ -0,0 +1,275 @@
1+
2+# Upgrading to 0.17
3+
4+Upgrading should be pretty easy. Everything is quite mechanical, so I would not be very afraid of this process.
5+
6+
7+## Update elm-package.json
8+
9+Some core packages have been renamed:
10+
11+ - `evancz/elm-html` is now `elm-lang/html`
12+ - `evancz/elm-svg` is now `elm-lang/svg`
13+ - `evancz/virtual-dom` is now `elm-lang/virtual-dom`
14+ - The functionality of `evancz/start-app` now lives in `elm-lang/html` in `Html.App`
15+ - The functionality of `evancz/elm-effects` now lives in `elm-lang/core` in `Platform.*`
16+ - The functionality of `Graphics.*` now lives in `evancz/elm-graphics`
17+
18+So the first thing you want to do is update your `elm-package.json` file. Here is one that has been properly updated:
19+
20+```json
21+{
22+ "version": "1.0.0",
23+ "summary": "let people do a cool thing in a fun way",
24+ "repository": "https://github.com/user/project.git",
25+ "license": "BSD3",
26+ "source-directories": [
27+ "src"
28+ ],
29+ "exposed-modules": [],
30+ "dependencies": {
31+ "elm-lang/core": "4.0.0 <= v < 5.0.0",
32+ "elm-lang/html": "1.0.0 <= v < 2.0.0",
33+ "evancz/elm-http": "3.0.1 <= v < 4.0.0",
34+ "evancz/elm-markdown": "3.0.0 <= v < 4.0.0"
35+ },
36+ "elm-version": "0.17.0 <= v < 0.18.0"
37+}
38+```
39+
40+The only changes should be in the `dependencies` and `elm-version` fields where you need to update constraints. The easiest way to get this all set up is to update `elm-version` by hand, and then remove everything from `dependencies` so you can install the dependencies you still need one at a time with `elm package install`.
41+
42+
43+## Updating Syntax
44+
45+The major syntax changes are:
46+
47+
48+<table>
49+ <tr>
50+ <th>feature</th>
51+ <th>0.16</th>
52+ <th>0.17</th>
53+ </tr>
54+
55+ <tr>
56+ <td>module declaration</td>
57+ <td><pre lang="elm">module Queue (..) where</pre></td>
58+ <td><pre lang="elm">module Queue exposing (..)</pre></td>
59+ </tr>
60+</table>
61+
62+This is a super easy change, so we will add a link to an auto-upgrade tool here when one exists.
63+
64+
65+## `Action` is now `Msg`
66+
67+The Elm Architecture tutorial uses the term `Action` for the data that gets fed into your `update` function. This is a silly name. So in 0.17 the standard name is *message*.
68+
69+```elm
70+-- 0.16
71+type Action = Increment | Decrement
72+
73+-- 0.17
74+type Msg = Increment | Decrement
75+```
76+
77+The idea is that your app is receiving *messages* from the user, from servers, from the browser, etc. Your app then reacts to these messages in the `update` function.
78+
79+
80+## No More `Signal.Address`
81+
82+The most common thing in your code will probably be that `Signal.Address` no longer exists. Here is a before and after of upgrading some typical `view` code.
83+
84+```elm
85+-- 0.16
86+view : Signal.Address Action -> Model -> Html
87+view address model =
88+ div []
89+ [ button [ onClick address Decrement ] [ text "-" ]
90+ , div [ countStyle ] [ text (toString model) ]
91+ , button [ onClick address Increment ] [ text "+" ]
92+ ]
93+
94+-- 0.17
95+view : Model -> Html Msg
96+view model =
97+ div []
98+ [ button [ onClick Decrement ] [ text "-" ]
99+ , div [ countStyle ] [ text (toString model) ]
100+ , button [ onClick Increment ] [ text "+" ]
101+ ]
102+```
103+
104+This change is pretty simple. Any occurance of `address` just gets deleted. In the types, you see the addresses removed, and `Html` becomes `Html Msg`. You can read `Html Msg` as "an HTML node that can produce messages of type `Msg`". This change makes addresses unnecessary and makes it much clearer what kind of messages can be produced by a particular block of HTML.
105+
106+The `Signal.forwardTo` function is replaced by `Html.App.map`. So you may need to make changes like this:
107+
108+```elm
109+-- 0.16
110+view : Signal.Address Action -> Model -> Html
111+view address model =
112+ div []
113+ [ Counter.view (Signal.forwardTo address Top) model.topCounter
114+ , Counter.view (Signal.forwardTo address Bottom) model.bottomCounter
115+ , button [ onClick address Reset ] [ text "RESET" ]
116+ ]
117+
118+-- 0.17
119+view : Model -> Html Msg
120+view model =
121+ div []
122+ [ map Top (Counter.view model.topCounter)
123+ , map Bottom (Counter.view model.bottomCounter)
124+ , button [ onClick Reset ] [ text "RESET" ]
125+ ]
126+```
127+
128+These changes are nice for a couple really good reasons:
129+
130+ - Addresses were consistently one of the things that new folks found most confusing.
131+ - It allows the `elm-lang/virtual-dom` implementation to be more efficient with `lazy`
132+ - It uses a normal `map` instead of some unfamiliar API.
133+
134+You can see more examples of the new HTML API [here](https://evancz.gitbooks.io/an-introduction-to-elm/content/architecture/user_input/index.html).
135+
136+
137+## `Effects` is now `Cmd`
138+
139+If you are working with HTTP or anything, you are probably using `evancz/elm-effects` and have your `update` function returning `Effects` values. That library was a successful experiment, so it has been folded into `elm-lang/core` and given a name that works better in the context of Elm 0.17.
140+
141+The changes are basically a simple rename:
142+
143+```elm
144+-- 0.16
145+update : Action -> Model -> (Model, Effects Action)
146+update action model =
147+ case action of
148+ RequestMore ->
149+ (model, getRandomGif model.topic)
150+
151+ NewGif maybeUrl ->
152+ ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl)
153+ , Effects.none
154+ )
155+
156+-- 0.17
157+update : Msg -> Model -> (Model, Cmd Msg)
158+update msg model =
159+ case msg of
160+ RequestMore ->
161+ ( model, getRandomGif model.topic )
162+
163+ NewGif maybeUrl ->
164+ ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl)
165+ , Cmd.none
166+ )
167+```
168+
169+The `Cmd` stuff lives in `elm-lang/core` in `Platform.Cmd`. It is imported by default with `import Platform.Cmd as Cmd exposing (Cmd)` to make it easier to use.
170+
171+Again, very easy changes. The key goal of 0.17 was to manage effects in a nicer way, so in making these facilities more complete, the term `Effects` became very ambiguous. You should read more about this in the updated Elm Architecture Tutorial which has [a section all about effects](https://evancz.gitbooks.io/an-introduction-to-elm/content/architecture/effects/index.html).
172+
173+
174+## `StartApp` is now `Html.App`
175+
176+The `evancz/start-app` package was an experiment to help people get productive with Elm more quickly. It meant that newcomers could get really far with Elm without knowing a ton about signals, and it has been very effective. With 0.17, it has been folded in to `elm-lang/html` in the `Html.App` module.
177+
178+Upgrading looks like this:
179+
180+```elm
181+-- 0.16 ---------------------------------------
182+import StartApp
183+import Task
184+
185+app =
186+ StartApp.start
187+ { init = init, update = update, view = view, inputs = [] }
188+
189+main =
190+ app.html
191+
192+port tasks : Signal (Task.Task Never ())
193+port tasks =
194+ app.tasks
195+
196+-- 0.17 ---------------------------------------
197+import Html.App as Html
198+
199+main =
200+ Html.program
201+ { init = init, update = update, view = view, subscriptions = \_ -> Sub.none }
202+```
203+
204+The type of `main` has changed from `Signal Html` to `Program flags`. The main value is a program that knows exactly how it needs to be set up. All that will be handled by Elm, so you no longer need to specially hook tasks up to a port or anything.
205+
206+
207+## Upgrading Ports
208+
209+Talking to JavaScript still uses ports. It is pretty similar, but adapted to fit nicely with commands and subscriptions.
210+
211+Here is the change for *outgoing* ports:
212+
213+```elm
214+-- 0.16
215+port focus : Signal String
216+port focus =
217+ ...
218+
219+-- 0.17
220+port focus : String -> Cmd msg
221+```
222+
223+Instead of hooking up a signal, you have a function that can create commands. So you just call `focus : String -> Cmd msg` from anywhere in your app and the command is processed like all the others.
224+
225+And here is the change for *incoming* ports:
226+
227+```elm
228+type User = { name : String, age : Int }
229+
230+-- 0.16
231+port users : Signal User
232+
233+-- 0.17
234+port users : (User -> msg) -> Sub msg
235+```
236+
237+Instead of getting a signal to route to the right place, we now can create subscriptions to incoming ports. So wherever you need to know about users, you just subscribe to it.
238+
239+You should definitely read more about this [here](https://evancz.gitbooks.io/an-introduction-to-elm/content/interop/javascript.html).
240+
241+
242+## JavaScript Interop
243+
244+The style of initializing Elm programs in JS has also changed slightly.
245+
246+<table>
247+ <tr>
248+ <th>Initialize</th>
249+ <th>0.16</th>
250+ <th>0.17</th>
251+ </tr>
252+
253+ <tr>
254+ <td>Embed</td>
255+ <td><pre lang="javascript">Elm.embed(Elm.Main, someNode);</pre></td>
256+ <td><pre lang="javascript">Elm.Main.embed(someNode);</pre></td>
257+ </tr>
258+
259+ <tr>
260+ <td>Fullscreen</td>
261+ <td><pre lang="javascript">Elm.fullscreen(Elm.Main);</pre></td>
262+ <td><pre lang="javascript">Elm.Main.fullscreen();</pre></td>
263+ </tr>
264+
265+ <tr>
266+ <td>Worker</td>
267+ <td><pre lang="javascript">Elm.worker(Elm.Main);</pre></td>
268+ <td><pre lang="javascript">Elm.Main.worker();</pre></td>
269+ </tr>
270+</table>
271+
272+
273+## Next Steps
274+
275+From here, I would highly recommend looking through [guide.elm-lang.org](http://guide.elm-lang.org/), particularly the sections on [The Elm Architecture](http://guide.elm-lang.org/architecture/index.html). This will help you get a feel for 0.17.