# Upgrading to 0.16

Upgrading should be pretty easy. Everything is quite mechanical, so I would not be very afraid of this process.


## Update elm-package.json

First thing you want to do is update your `elm-package.json` file. The fields that need work are `repository`, `elm-version`, and `dependencies`.

If you have some dummy information in `repository`, something like `https://github.com/USER/PROJECT.git`, you will need to change it such that the project is all lower case. This should work: `https://github.com/user/project.git`.

Here is a working `elm-version`:

```json
{
    "elm-version": "0.16.0 <= v < 0.17.0"
}
```

Here are the latest bounds for a bunch of `dependencies`.

```json
{
    "dependencies": {
        "elm-lang/core": "3.0.0 <= v < 4.0.0",
        "evancz/elm-effects": "2.0.1 <= v < 3.0.0",
        "evancz/elm-html": "4.0.2 <= v < 5.0.0",
        "evancz/elm-http": "3.0.0 <= v < 4.0.0",
        "evancz/elm-markdown": "2.0.0 <= v < 3.0.0",
        "evancz/elm-svg": "2.0.1 <= v < 3.0.0",
        "evancz/start-app": "2.0.2 <= v < 3.0.0"
    },
}
```

The easiest way to get this all set up is to remove everything from `dependencies` and just install the things you need one at a time with `elm-package install`.

## Updating Syntax

The major syntax changes are:

     feature
     0.15.1 
     0.16

     field update
     
{ record | x <- 42 }

{ record | x = 42 }

     field addition
     
{ record | x = 42 }

     removed

     field deletion
     
{ record - x }

     removed

     record constructors that add fields
     
type alias Named r =
  { r | name : String }
  
-- generates a function like this:
-- Named : String -> r -> Named r

type alias Named r =
  { r | name : String }

Generates no function. Field addition is gone. A function
will still be generated for "closed" records though.

     field parameters
     
type alias Foo =
  { prefix : String -> String }

foo : Foo
foo = { prefix x = "prefix" ++ x }

type alias Foo =
  { prefix : String -> String }

foo : Foo
foo = { prefix = \x-> "prefix" ++ x }

     multi-way if
     
if | x < 0 -> "left"
   | x > 0 -> "right"
   | otherwise -> "neither"

if x < 0 then
    "left"

else if x > 0 then
    "right"

else
    "neither"

The most common by far should be the record update change. That was the only syntax that used the `<-` operator, so you can pretty safely do a find-and-replace from `<-` to `=` and be all set.

The multi-way if is also pretty easy. You just translate it into the equivalent `if/then/else` construct. As you are doing this, notice the style used. It should look quite a bit like Python or any C-like language really. You start with an `if` and do `else if` until you are done. The body of each branch should be indented and things look way nicer if you have a blank line between each branch. I sometimes put a blank line above and below each branch, especially when the branch is more complex.

If you are using field addition and deletion, it is possible to translate your code into:

  1. A union type that models things with a simpler API, like [in this case](https://github.com/elm-lang/elm-compiler/issues/985#issuecomment-121927230).
  2. Nesting records instead of adding things onto them. Rather than adding a field, create an outer record that contains a field for the two things you are trying to put together. This seems to lead to nicer code in the long run.


## Incomplete Pattern Matches

As of 0.16, incomplete pattern matches are caught at compile time as errors. This is true both of `case` expressions and function arguments.

As I updated things, I ran into this only when I had been tricky with `Maybe` and `List` where I knew something about their structure based on some incidental details. The nicest example of this was [some code in package.elm-lang.org](https://gist.github.com/evancz/e590750a5bd1ea04c2d2) where the priority has often been "get it working" over "excellent quality code".

The compiler should give you pretty nice hints in all these cases, so I think the best advice is just to expect this sort of thing and treat it as an oppurtunity to clean your code up a bit where you were being tricky.


## Updating Library Usages

There is not actually a lot that changed in `elm-lang/core` and in `evancz/*` libraries.

The most noticable removals will be:

  * `Basics.otherwise`
  * `Signal.(<~)`
  * `Signal.(~)`

`otherwise` is gone because it is very useless without the multi-way if syntax.

Removing `(<~)` and `(~)` is in the spirit of "infix functions should be avoided" and the overall move towards removing redundant and ugly syntax in this release. You can instead use `Signal.mapN` to fill the void here. If you are combining a ton of signals, you can redefine the equivalent of `(~)` like this:

```elm
andMap : Signal (a -> b) -> Signal a -> Signal b
andMap =
  Signal.map2 (<|)
```

Otherwise it is pretty much all small bug fixes and improvements to documentation.
