# Upgrading to 0.18

Like always, not that much has really changed. To make the process as smooth as possible, this document outlines all the things you will want to do to use 0.18.

  - [Update `elm-package.json`](#update-elm-packagejson)
  - [List Ranges](#list-ranges)
  - [No More Primes](#no-more-primes)
  - [Backticks and `andThen`](#backticks-and-andthen)
  - [Renamed Functions in Core](#renamed-functions-in-core)
  - [Package Changes](#package-changes)

A lot of this can be done automatically with [`elm-upgrade`](https://github.com/avh4/elm-upgrade#elm-upgrade), so check it out after reading through this document!


## Update elm-package.json

So the first thing you want to do is update your `elm-package.json` file. The only tricky thing is that the HTTP package moved:

  - `evancz/elm-http` => [`elm-lang/http`](http://package.elm-lang.org/packages/elm-lang/http/latest)

From there, here is an `elm-package.json` that has been properly updated:

```json
{
    "version": "1.0.0",
    "summary": "let people do a cool thing in a fun way",
    "repository": "https://github.com/user/project.git",
    "license": "BSD3",
    "source-directories": [
        "src"
    ],
    "exposed-modules": [],
    "dependencies": {
        "elm-lang/core": "5.0.0 <= v < 6.0.0",
        "elm-lang/html": "2.0.0 <= v < 3.0.0",
        "elm-lang/http": "1.0.0 <= v < 2.0.0",
        "evancz/elm-markdown": "3.0.1 <= v < 4.0.0"
    },
    "elm-version": "0.18.0 <= v < 0.19.0"
}
```

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 use [`elm-upgrade`](https://github.com/avh4/elm-upgrade#elm-upgrade), but you can also:

  - Update `elm-version` by hand.
  - Remove everything from `dependencies` by hand.
  - Install what you need with `elm-package install elm-lang/core` one-by-one.


## List Ranges

The `[1..5]` syntax has been removed.

So replace any occurance of `[1..9]` with `List.range 1 9`.


## No More Primes

You are not allowed to have primes in variable names, so things like `type'` are renamed to `type_`.


## Backticks and `andThen`

Elm used to let you take normal functions and use them as infix operators. This is most notable in the case of `andThen` which is pretty much the only function that used this feature. You will want to make the following updates to your code:

```elm
-- old

andThenIn17 : Result String Int
andThenIn17 =
  String.toInt "1234"
    `Result.andThen` \year -> isValidYear year

-- andThen : Result x a -> (a -> Result x b) -> Result x b


-- new

andThenIn18 : Result String Int
andThenIn18 =
  String.toInt "1234"
    |> Result.andThen (\year -> isValidYear year)

-- andThen : (a -> Result x b) -> Result x a -> Result x b
```

Notice that the backtick style is replaced by pipelining. The `onError` function has been flipped in the same way, so if you are working with tasks you may say something like this in 0.18:

```elm
type Msg = NewText String | DidNotLoad

tasksIn18 : Task x Msg
tasksIn18 =
  Http.toTask (Http.getString "http://example.com/war-and-peace")
    |> Task.andThen (\fullText -> Task.succeed (NewText fullText))
    |> Task.onError (\error -> Task.succeed DidNotLoad)
```

This also means that `andThen` and `onError` group together much better than in the infix style.

**This change should be happening across the entire Elm ecosystem as package authors upgrade to 0.18.**


## Renamed Functions in Core

A couple functions have been removed or renamed.

  - [`Json.Decode`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Json-Decode)
    - `objectN` becomes `mapN` (Note: `object1` becomes `map`) 
    - `tupleN` becomes `mapN` with `index`
    - `(:=)` becomes `field`
    - `andThen` args flip

  - [`Bitwise`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Bitwise)
    - `shiftLeft` becomes `shiftLeftBy` and args flip
    - `shiftRight` becomes `shiftRightBy` and args flip
    - `shiftRightLogical` becomes `shiftRightZfBy` and args flip

  - [`Task`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Task)
    - `andThen` args flip
    - `onError` args flip
    - Removed `perform : (x -> msg) -> (a -> msg) -> Task x a -> Cmd msg`
    - Added  `perform : (a -> msg) -> Task Never a -> Cmd msg`
    - Added  `attempt : (Result x a -> msg) -> Task x a -> Cmd msg`
    - Removed `toMaybe` and `toResult` in favor of using `onError` directly

  - [`Result`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Result)
    - Renamed `formatError` to `mapError` to match names in `Task`
    - `andThen` args flip

  - [`Maybe`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Maybe)
    - `andThen` args flip
    - Removed `oneOf`

  - [`Random`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Random)
    - `andThen` args flip

  - [`Tuple`](http://package.elm-lang.org/packages/elm-lang/core/5.0.0/Tuple)
    - `Basics.fst` becomes `Tuple.first`
    - `Basics.snd` becomes `Tuple.second`


## Package Changes

The following packages have changed a little bit:

  - [`elm-lang/html`](http://package.elm-lang.org/packages/elm-lang/html/latest) collapsed `Html.App` into `Html`. So you need to remove any `import Html.App` imports and refer to `Html.program` instead.

  - [`elm-lang/http`](http://package.elm-lang.org/packages/elm-lang/http/latest) was redone to be easier and have more features. It now supports tracking progress and rate-limiting HTTP requests. It should be pretty easy to upgrade to the new stuff, but if you have a complex `Task` that chains many requests, you will want to use the `Http.toTask` function to keep that code working the same.

  - [`elm-lang/navigation`](http://package.elm-lang.org/packages/elm-lang/navigation/latest) no longer has its own concept of a `Parser`. You just turn a `Navigation.Location` into a message and it is fed into your normal `update` function. This means `Navigation.program` is now much closer to `Html.program` so this should simplify things a bit.

  - [`evancz/url-parser`](http://package.elm-lang.org/packages/evancz/url-parser/latest) is pretty much the same, but works better and is friendlier. New things include:
    - You can use `<?>` to parse query parameters.
    - Some bugs about parsing leading and trailing slashes are fixed.
    - The parser backtracks, always finding a valid parse of the URL if one exists.
    - You can use `parsePath` to parse a `Navigation.Location` directly.

In all cases, the packages have become simpler and easier to use. The actual changes did not seem to be too serious as I upgraded `elm-lang.org` and `package.elm-lang.org` and all the examples I control.
