### Upgrade Instructions/0.16 # 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. --- ### Upgrade Instructions/0.17 # Upgrading to 0.17 Upgrading should be pretty easy. Everything is quite mechanical, so I would not be very afraid of this process. ## Update elm-package.json Some core packages have been renamed: - `evancz/elm-html` is now `elm-lang/html` - `evancz/elm-svg` is now `elm-lang/svg` - `evancz/virtual-dom` is now `elm-lang/virtual-dom` - The functionality of `evancz/start-app` now lives in `elm-lang/html` in `Html.App` - The functionality of `evancz/elm-effects` now lives in `elm-lang/core` in `Platform.*` - The functionality of `Graphics.*` now lives in `evancz/elm-graphics` So the first thing you want to do is update your `elm-package.json` file. Here is one 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": "4.0.0 <= v < 5.0.0", "elm-lang/html": "1.0.0 <= v < 2.0.0", "evancz/elm-http": "3.0.1 <= v < 4.0.0", "evancz/elm-markdown": "3.0.0 <= v < 4.0.0" }, "elm-version": "0.17.0 <= v < 0.18.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 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`. ## Updating Syntax The major syntax changes are:
feature 0.16 0.17
module declaration
module Queue (..) where
module Queue exposing (..)
This is a super easy change, so we will add a link to an auto-upgrade tool here when one exists. ## `Action` is now `Msg` 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*. ```elm -- 0.16 type Action = Increment | Decrement -- 0.17 type Msg = Increment | Decrement ``` 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. ## No More `Signal.Address` 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. ```elm -- 0.16 view : Signal.Address Action -> Model -> Html view address model = div [] [ button [ onClick address Decrement ] [ text "-" ] , div [ countStyle ] [ text (toString model) ] , button [ onClick address Increment ] [ text "+" ] ] -- 0.17 view : Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [ countStyle ] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] ``` 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. The `Signal.forwardTo` function is replaced by `Html.App.map`. So you may need to make changes like this: ```elm -- 0.16 view : Signal.Address Action -> Model -> Html view address model = div [] [ Counter.view (Signal.forwardTo address Top) model.topCounter , Counter.view (Signal.forwardTo address Bottom) model.bottomCounter , button [ onClick address Reset ] [ text "RESET" ] ] -- 0.17 view : Model -> Html Msg view model = div [] [ map Top (Counter.view model.topCounter) , map Bottom (Counter.view model.bottomCounter) , button [ onClick Reset ] [ text "RESET" ] ] ``` These changes are nice for a couple really good reasons: - Addresses were consistently one of the things that new folks found most confusing. - It allows the `elm-lang/virtual-dom` implementation to be more efficient with `lazy` - It uses a normal `map` instead of some unfamiliar API. 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). ## `Effects` is now `Cmd` 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. The changes are basically a simple rename: ```elm -- 0.16 update : Action -> Model -> (Model, Effects Action) update action model = case action of RequestMore -> (model, getRandomGif model.topic) NewGif maybeUrl -> ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl) , Effects.none ) -- 0.17 update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of RequestMore -> ( model, getRandomGif model.topic ) NewGif maybeUrl -> ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl) , Cmd.none ) ``` 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. 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). ## `StartApp` is now `Html.App` 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. Upgrading looks like this: ```elm -- 0.16 --------------------------------------- import StartApp import Task app = StartApp.start { init = init, update = update, view = view, inputs = [] } main = app.html port tasks : Signal (Task.Task Never ()) port tasks = app.tasks -- 0.17 --------------------------------------- import Html.App as Html main = Html.program { init = init, update = update, view = view, subscriptions = \_ -> Sub.none } ``` 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. ## Upgrading Ports Talking to JavaScript still uses ports. It is pretty similar, but adapted to fit nicely with commands and subscriptions. Here is the change for *outgoing* ports: ```elm -- 0.16 port focus : Signal String port focus = ... -- 0.17 port focus : String -> Cmd msg ``` 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. And here is the change for *incoming* ports: ```elm type User = { name : String, age : Int } -- 0.16 port users : Signal User -- 0.17 port users : (User -> msg) -> Sub msg ``` 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. You should definitely read more about this [here](https://evancz.gitbooks.io/an-introduction-to-elm/content/interop/javascript.html). ## JavaScript Interop The style of initializing Elm programs in JS has also changed slightly.
Initialize 0.16 0.17
Embed
Elm.embed(Elm.Main, someNode);
Elm.Main.embed(someNode);
Fullscreen
Elm.fullscreen(Elm.Main);
Elm.Main.fullscreen();
Worker
Elm.worker(Elm.Main);
Elm.Main.worker();
## Next Steps 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. --- ### Upgrade Instructions/0.18 # 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. --- ### Upgrade Instructions/0.19.0 # Upgrading to 0.19 To make the process as smooth as possible, this document outlines all the things you need to do to upgrade to 0.19. - [Command Line](#command-line) - [`elm.json`](#elmjson) - [Changes](#changes) - [`--optimize`](#--optimize) - [Compiler Performance](#compiler-performance) - [Parse Errors](#parse-errors) - [Stricter Record Update Syntax](#stricter-record-update-syntax) - [Removed User-Defined Operators](#removed-user-defined-operators) > **Note:** You can try out [`elm-upgrade`](https://github.com/avh4/elm-upgrade#elm-upgrade--) which automates some of the 0.18 to 0.19 changes. It is also in an alpha stage, and Aaron has said it makes sense to talk things through [here](https://github.com/avh4/elm-upgrade/issues).
## Command Line There is now just one `elm` binary at the command line. The terminal commands are now: ```bash # 0.19 # 0.18 elm make # elm-make elm repl # elm-repl elm reactor # elm-reactor elm install # elm-package install elm publish # elm-package publish elm bump # elm-package bump elm diff # elm-package diff ```
## `elm.json` `elm-package.json` becomes `elm.json` which is specialized for applications and packages. For example, it helps you lock your dependencies in applications and get broad dependency ranges in packages. See the full outlines here: - `elm.json` for [applications](https://github.com/elm/compiler/blob/main/docs/elm.json/application.md) - `elm.json` for [packages](https://github.com/elm/compiler/blob/main/docs/elm.json/package.md) Both are quite similar to the `elm-package.json` format, and `elm-upgrade` can help you with this.
## Changes #### Functions Changed - `String.toInt : String -> Maybe Int` (not `Result` anymore) - `String.toFloat : String -> Maybe Float` (not `Result` anymore) - `Basics.toString` becomes [`Debug.toString`](https://package.elm-lang.org/packages/elm/core/latest/Debug#toString), [`String.fromInt`](https://package.elm-lang.org/packages/elm/core/latest/String#fromInt), and [`String.fromFloat`](https://package.elm-lang.org/packages/elm/core/latest/String#fromFloat). - `Basics.rem 451 10` becomes [`remainderBy 10 451`](https://package.elm-lang.org/packages/elm/core/latest/Basics#remainderBy) - `451 % 10` becomes [`modBy 10 451`](https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy) - `(,)` becomes [`Tuple.pair`](https://package.elm-lang.org/packages/elm/core/latest/Tuple#pair) - `style : List (String, String) -> Attribute msg` becomes `String -> String -> Attribute msg` - `Html.beginnerProgram` becomes [`Browser.sandbox`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#sandbox). - `Html.program` becomes [`Browser.element`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#element) and [`Browser.document`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#document). #### Modules Moved - `Json.Encode` and `Json.Decode` moved to [`elm/json`](https://package.elm-lang.org/packages/elm/json/latest) - `Time` and `Date` moved to [`elm/time`](https://package.elm-lang.org/packages/elm/time/latest/) with a significantly improved API - `Random` moved to [`elm/random`](https://package.elm-lang.org/packages/elm/random/latest/) with a better implementation and a few new functions - `Regex` moved to [`elm/regex`](https://package.elm-lang.org/packages/elm/regex/latest) with a much clearer README #### Packages Moved - `elm-lang/*` moved to `elm/*` - `evancz/url-parser` moved to [`elm/url`](https://package.elm-lang.org/packages/elm/url/latest) with a simpler and more flexible API - `elm-tools/elm-parser` moved to [`elm/parser`](https://package.elm-lang.org/packages/elm/parser/latest) with speed boost when compiling with the `--optimize` flag - [`elm/browser`](https://package.elm-lang.org/packages/elm/browser/latest) combines and simplifies the following 0.18 packages: - `elm-lang/navigation` with smoother APIs - `elm-lang/dom` with ability to get node positions and dimensions. - `elm-lang/mouse` with decoders - `elm-lang/window` - `elm-lang/keyboard` uses decoders like [this](https://github.com/elm/browser/blob/master/notes/keyboard.md) - `elm-lang/page-visibility` - `elm-lang/animation-frame` #### Functions Removed - `uncurry` - `curry` - `flip` - `(!)` Prefer named helper functions in these cases.
## `--optimize` You can now compile with `elm make --optimize` which enables things like: - Reliable field name shortening in compiled assets - Unbox things like `type Height = Height Float` to just be a float at runtime - Unbox `Char` values - Use more compact names for `type` constructors in compiled assets. Some of these optimizations require "forgetting information" that is useful while debugging, so the `Debug` module becomes unavailable when you add the `--optimize` flag. The idea being that you want to be shipping code with this flag (like `-O2` in C) but not compiling with it all day in development.
## Compiler Performance I did a bunch of performance optimizations for the compiler itself. For example: - I rewrote the parser to be very significantly faster (partly by allocating very little!) - I revamped how type inference looks up the type of foreign variables to be `O(1)` rather than `O(log(n))` - I redid how code is generated to allow DCE with declarations as the level of granuality - Packages are downloaded once per user and saved in `~/.elm/` - Packages are built once for any given set of dependencies, so they do not contribute to build times of fresh projects. Point is, the compiler is very significantly faster!
## Parse Errors Part of rewriting the parser was making nicer parse errors. Many people only really see them when getting started, and rather than saying "man, these are terrible" they think "man, programming is hard" leading to a big underreporting of quality issues here. Anyway, please explore that a bit and see if you run into anything odd!
## Stricter Record Update Syntax It used to be possible for `{ r | x = v }` to change the type of field `x`. This is no longer possible. This greatly improves the quality of error messages in many cases. You can still change the type of a field, but you must reconstruct the record with the record literal syntax, or with a record constructor. The idea is that 99.9% of uses get a much better experience with type errors, whereas 0.1% of uses become somewhat more verbose. As someone who had a bit of code that changed record types, I have found this to be a really excellent trade.
## Removed User-Defined Operators It is no longer possible to define custom operators. For example, someone defined: ```elm (|-~->) : (a -> a1_1 -> a3) -> (a2 -> a1_1) -> a -> a2 -> a3 ``` They are still able to define that function, but it will need a human readable name that explains what it is meant to do. The reasoning behind this decision is outlined in detail in [this document](https://gist.github.com/evancz/769bba8abb9ddc3bf81d69fa80cc76b1).
## Notes: - `toString` — A relatively common bug was to show an `Int` in the UI, and then later that value changes to something else. `toString` would just show wrong information until someone noticed. The new `String.fromInt` and `String.fromFloat` ensure that cannot happen. Furthermore, more elaborate types almost certainly need localization or internationalization, which should be handled differently anyway. --- ### Upgrade Instructions/0.19.1 # Upgrading to 0.19.1 **There are no language changes**, so once you swap to `"elm-version": "0.19.1"` in your `elm.json`, most users should be able to proceed without any further code changes. **You may run into a handful of bugfixes though!** These cases are outlined below!
## Improvements - Parse error message quality (like [this](https://github.com/elm/error-message-catalog/issues/255) and [this](https://github.com/elm/error-message-catalog/issues/225)) - Faster compilation, especially for incremental compiles - Uses filelocks so that cached files are not corrupted when plugins run `elm make` multiple times on the same project at the same time. (Still worth avoiding that though!) - More intuitive multiline declarations in REPL - Various bug fixes (e.g. `--debug`, `x /= 0`, `type Height = Height Float` in `--optimize`)
## Detectable Bug Fixes There are three known cases where code that compiled with 0.19.0 will not compile with 0.19.1 due to bug fixes: ### 1. Ambiguous Imports Say you have an import like this: ```elm import Html exposing (min) import Regex exposing (never) x = min y = never ``` These should be reported as ambiguous usages since the names are also exposed by `Basics`, but there was a regression in 0.19.0 described [here](https://github.com/elm/compiler/issues/1945) such that they weren't caught in specific circumstances. The fix is to use a qualified name like `Html.min` or `Regex.never` to make it unambiguous. We found a couple instances of this in packages and have submitted PRs to the relevant authors in August 2019. You may run into this in your own code as well. For more details on why this is considered a regression, check out the details [here](https://github.com/elm/compiler/issues/1945#issuecomment-507871919) or try it in 0.18.0 to see how it worked before. ### 2. Tabs in Comments The 0.19.0 binaries did not catch tab characters in comments. The new parser is better at checking for tabs, so it will object when it finds these. Again, we found this in some packages and reached out to the relevant authors with PRs so patches would be published before the 0.19.1 release. ### 3. Port Module with no Ports If you have any files that start with: ```elm port module Main exposing (..) ``` But they do not actually have any `port` declarations, the 0.19.1 binary will ask you to switch to a normal module declaration like `module Main exposing (..)` --- ### Upgrade Instructions/Earlier # 0.16 Read all about it at these links: * http://elm-lang.org/blog/compilers-as-assistants * https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.16.md # 0.15 ### Improve Import Syntax The changes in 0.14 meant that people were seeing pretty long import sections, sometimes with two lines for a single module to bring it in qualified and to expose some unqualified values. The new syntax is like this: ```elm import List -- Just bring `List` into scope, allowing you to say `List.map`, -- `List.filter`, etc. import List exposing (map, filter) -- Bring `List` into scope, but also bring in `map` and `filter` -- without any prefix. import List exposing (..) -- Bring `List` into scope, and bring in all the values in the -- module without a prefix. import List as L -- Bring `L` into scope, but not `List`. This lets you say `L.map`, -- `L.filter`, etc. import List as L exposing (map, filter) -- Bring `L` into scope along with unqualified versions of `map` -- and `filter`. import List as L exposing (..) -- Bring in all the values unqualified and qualified with `L`. ``` This means you are doing more with each import, writing less overall. It also makes the default imports more comprehensive because you now can refer to `List` and `Result` without importing them explicitly as they are in the defaults. ### Revise Port Syntax One common confusion with the `port` syntax is that the only difference between incoming ports and outgoing ports is whether the type annotation comes with a definition. To make things a bit clearer, we are using the keywords `foreign input` and `foreign output`. ```elm foreign input dbResults : Stream String foreign output dbRequests : Stream String foreign output dbRequests = Stream.map toRequest userNames ``` ### Input / Output The biggest change in 0.15 is the addition of tasks, allowing us to represent arbitrary effects in Elm in a safe way. This parallels how ports work, so we are trying to draw attention to that in syntax. First addition is a way to create new inputs to an Elm program. ```elm input actions : Input Action ``` This creates a `Input` that is made up of an `Address` you can send messages to and a `Stream` of those messages. This is similar to a `foreign input` except there we use the name as the address. The second addition is a way to run tasks. ```elm output Stream.map toRequest userNames ``` This lets us turn tasks into effects in the world. Sometimes it is useful to pipe the results of these tasks back into Elm. For that, we have the third and final addition. ```elm input results : Stream (Result Http.Error String) input results from Stream.map toRequest userNames ``` # 0.14.1 Modify default import of `List` to expose `(::)` as well. # 0.14 ### Breaking Changes * Keyword `data` renamed to `type` * Keyword `type` renamed to `type alias` # 0.13 ### Improvements: * Type aliases in port types * Add Keyboard.alt and Keyboard.meta * Add Debug.crash, Debug.watch, Debug.watchSummary, and Debug.trace * Add List.indexedMap and List.filterMap * Add Maybe.map * Add Basics.negate * Add (>>) to Basics as in F# * Add --bundle-runtime flag which creates stand-alone Elm programs * Error on ambiguious use of imported variables * Replace dependency on Pandoc with cheapskate+kate * Better architecture for compiler. Uses types to make compilation pipeline safer, setting things up for giving programmatic access to the AST to improve editor and IDE support. ### Breaking Changes: * Rename (.) to (<<) as in F# * Rename Basics.id to Basics.identity * Rename Basics.div to (//) * Rename Basics.mod to (%) * Remove Maybe.justs for (List.filterMap identity) * Remove List.and for (List.foldl (&&) True) * Remove List.or for (List.foldl (||) False) * Unambiguous syntax for importing ADTs and type aliases * sqrt and logBase both only work on Floats now # 0.12.3 * Minor changes to support webgl as a separate library * Switch from HSV to HSL * Programmatic access to colors with toHsl and toRgb # 0.12.1 ### Improvements: * New Array library (thanks entirely to @Xashili) * Json.Value can flow through ports * Improve speed and stack usage in List library (thanks to @maxsnew) * Add Dict.filter and Dict.partition (thanks to @hdgarrood) ### Breaking Changes: * Revamp Json library, simpler with better names * Revamp JavaScript.Experimental library to have slightly better names * Remove JavaScript library which was made redundant by ports # 0.12 ### Breaking Changes: * Overhaul Graphics.Input library (inspired by Spiros Eliopoulos and Jeff Smitts) * Overhaul Text library to accomodate new Graphics.Input.Field library and make the API more consistent overall * Overhaul Regex library (inspired by Attila Gazso) * Change syntax for "import open List" to "import List (..)" * Improved JSON format for types generated by elm-doc * Remove problematic Mouse.isClicked signal * Revise the semantics of keepWhen and dropWhen to only update when the filtered signal changes (thanks Max New and Janis Voigtländer) ### Improvements: * Add Graphics.Input.Field for customizable text fields * Add Trampoline library (thanks to @maxsnew and @timthelion) * Add Debug library (inspired by @timthelion) * Drastically improved performance on markdown parsing (thanks to @Dandandan) * Add Date.fromTime function * Use pointer-events to detect hovers on layered elements (thanks to @Xashili) * Fix bugs in Bitwise library * Fix bug when exporting Maybe values through ports # 0.11 * Ports, a new FFI that is more general and much nicer to use * Basic compiler tests (thanks to Max New) # 0.10.1 * sort, sortBy, sortWith (thanks to Max Goldstein) * elm-repl * Bitwise library * Regex library * Improve Transform2D library (thanks to Michael Søndergaard) # 0.10 * Native strings * Tango colors * custom precedence and associativity for infix operators * elm-doc released with new documentation format * Realiasing in type errors * Rename Matrix2D => Transform2D * Add Random.floatList (thank you Max GoldStein) * Fix remove function in Dict (thank you Max New) * Start using language-ecmascript for JS generation * Make compatable with cabal-1.18 (thank you Justin Leitgeb) * All functions with 10+ arguments (thanks to Max New) # 0.9.1 * Allow custom precedence and associativity for user-defined infix ops * Realias types before printing * Switch to Tango color scheme, adding a bunch of nice colors * add the greyscale function for easily producing greys * Check the type of main * Fix miscellaneous bugs in type checker * Switch name of Matrix2D to Transform2D # 0.9 Build Improvements: * Major speed improvements to type-checker * Type-checker should catch _all_ type errors now * Module-level compilation, only re-compile if necessary * Import types and type aliases between modules * Intermediate files are generated to avoid unneeded recompilation and shorten compile time. These files go in ElmFiles/ by default * Generated files are placed in ElmFiles/ by default, replicating the directory structure of your source code. Error Messages: * Cross-module type errors * Errors for undefined values * Pretty printing of expressions and types Syntax: * Pattern matching on literals * Pattern aliases with `as` (Andrew) * Unary negation * Triple-quoted multi-line strings * Type annotations in let expressions (Andrew) * Record Constructors * Record type aliases can be closed on the zeroth column * (,,) syntax in types * Allow infix op definitions without args: (*) = add * Unparenthesized if, let, case, lambda at end of binary expressions elm-server: * Build multi-module projects * Report all errors in browser Libraries: * Detect hovering over any Element * Set alpha of arbitrary forms in collages * Switch Text.height to use px instead of em Bug Fixes: * Many bug fixes for collage, especially when rendering Elements. Website: * Hot-swapping * Much faster page load with pre-compiled Elm files (Max New) forgot to fill this in again... # 0.7.2 * Add a WebSockets library. * Add support for the mathematical looking operator for function composition (U+2218). forgot to fill this in for a while... # 0.5.0 * Add Dict, Set, and Automaton libraries! * Add (,,) notation for creating tuples. * Redo HTTP library, allowing any kind of request and more flexibility. * Remove the library prefixes `Data.`, `Graphics.`, and `Signal.` because they were more confusing than helpful. * Better type error reporting for ambiguous uses of variables and for variables in aliased modules. * Add `readInt` and `readFloat` functions. * Add `complement` function to compute complementary colors. * Ensure that `String` is treated as an alias of `[Char]`. * Fix bug in pattern parsing. `A B _ _` was parsed as `A (B _ _)`. * Make pattern matching a bit more compact in generated code. * Make generated JS more readable. * The Haskell API exports the absolute path to the Elm runtime system (with the corresponding version number). This makes it easier to run Elm programs with less setup. # 0.4.0 This version is all about graphics: nicer API with more features and major efficiency improvements. I am really excited about this release! * Add native Markdown support. You can now embed markdown directly in .elm files and it is used as an `Element`. Syntax is `[markdown| ... |]` where `...` is formatted as described [here](http://daringfireball.net/projects/markdown/). Content can span multiple lines too. * Drastically improve the `collage` interface. You can now move, rotate, and scale the following forms: - Elements (any Element you want can be turned into a Form with `toForm`) - Images - Shapes (shapes can be textured now too) - Lines This will make it way easier to make games in Elm. Games can now include text, gifs, videos, and any other Element you can think of. * Add `--minify` flag, to minify JS code. * Significantly improve performance of pattern matching. * Compiler performs beta-reduction in some simple cases. * The rendering section of the Elm runtume-system (RTS) has been totally rewritten, making screen refreshes use fewer cycles, less memory, and cause less garbage-collection. # 0.3.6 * Add JSON library. * Type-error messages improved. Gives better context for error, making them easier to find. Better messages for runtime errors as well (errors that the type checker cannot find yet). * Add Comparable super-type which allows the comparision of any values of type {Int,Float,Char,String}. Now possible to make Set and Map libraries. * Parser now handles decimal numbers. * Added many new functions for manipulating numbers: - truncate, round, floor, ceiling :: Float -> Int - toFloat :: Int -> Float - (^) :: Number -> Number -> Number - e :: Float * Foreign import/export statements no longer have to preceed all other variable and datatype definitions. They can be mixed in, making things a bit more readable/natural. * Bug fixes: - The `toText` function did not escape strings properly - Correct `castJSTupleToTupleN` family of functions - `foldr1` took the leftmost element as the base case instead of the rightmost - Fix minor display issue in latest version of Chrome. - Fix behavior of [ lo .. hi ] syntax (now [4..0] == [], not [0]). # 0.3.5 * Add JavaScript event interface. Allows Elm to import and export JS values and events. This makes it possible to import and export Elements, so users can use JS techniques and libraries if necessary. Conversion between JS and Elm values happens with functions from here: http://localhost:8000/docs/Foreign/JavaScript.elm http://localhost:8000/docs/Foreign/JavaScript/Experimental.elm * Add new flags to help with JavaScript event interface. * Add three built-in event listeners (elm_title, elm_log, elm_redirect) that make it possible to make some common/simple imperative actions without having to worry about writing the JS yourself. For example: foreign export jsevent "elm_title" title :: Signal JSString will update the page's title to the current value of the title signal. Empty strings are ignored. "elm_redirect" and "elm_log" events work much the same way, except that "elm_log" does not skip empty strings. * Add new Signal functions: count :: Signal a -> Signal Int 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 clicks :: Signal () The keep and drop functions make it possible to filter events, which was not possible in prior releases. More documentation: http://elm-lang.org/docs/Signal/Signal.elm * Add examples of JS event interface and new signal functions: https://github.com/evancz/Elm/tree/master/Examples/elm-js * Use more compressed format for strings. 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. * Add new function to Data.List: last :: [a] -> a * Fix parenthesization bug with binary operators. # 0.3.0 ### Major Changes (Read this part!) * Add a basic module system. * Elm's JavaScript runtime is now distributed with the elm package. Previously it was available for download as an unversioned JavaScript file (elm-mini.js). It is now installed with the elm compiler as elm-runtime-0.3.0.js. Be sure to serve the Elm runtime system that matches the version of the compiler used to generate JavaScript. When working locally, the compiler will automatically use your local copy of this file. * BREAKING CHANGE: rgb and rgba (in the color module) now take their red, green, and blue components as integers between 0 and 255 inclusive. * Improve error messages for parse errors and runtime errors. ### New Functions and Other Additions * Add support for keyboard events: Keyboard.Raw * Add buttons in Signal.Input: button :: String -> (Element, Signal Bool) * Add new basic element (an empty rectangle, good for adding spaces): rectangle :: Int -> Int -> Element * Add (an awkwardly named) way to display right justified text: rightedText * Add two basic libraries: Data.Char and Data.Maybe * Add some new colors: magenta, yellow, cyan, gray, grey * Add functions to Data.List module: take, drop * Add functions to Prelude (the default imports): fst, snd, curry, uncurry, and a bunch of list functions * Add --make, --separate-js, and --only-js flags to help compile with the new module system. --- ### Elm.Json/Application # `elm.json` for applications This is a decent baseline for pretty much any applications made with Elm. You will need these dependencies or more. ```json { "type": "application", "source-directories": [ "src" ], "elm-version": "0.19.2", "dependencies": { "direct": { "elm/browser": "1.0.0", "elm/core": "1.0.0", "elm/html": "1.0.0", "elm/json": "1.0.0" }, "indirect": { "elm/time": "1.0.0", "elm/url": "1.0.0", "elm/virtual-dom": "1.0.0" } }, "test-dependencies": { "direct": {}, "indirect": {} } } ```
## `"type"` Either `"application"` or `"package"`. All the other fields are based on this choice!
## `"source-directories"` A list of directories where Elm code lives. Most projects just use `"src"` for everything.
## `"elm-version"` The exact version of Elm this builds with. Should be `"0.19.2"` for most people!
## `"dependencies"` All the packages you depend upon. We use exact versions, so your `elm.json` file doubles as a "lock file" that ensures reliable builds. You can use modules from any `"direct"` dependency in your code. Some `"direct"` dependencies have their own dependencies that folks typically do not care about. These are the `"indirect"` dependencies. They are listed explicitly so that (1) builds are reproducible and (2) you can easily review the quantity and quality of dependencies. **Note:** We plan to eventually have a screen in `reactor` that helps add, remove, and upgrade packages. It can sometimes be tricky to keep all of the constraints happy, so we think having a UI will help a lot. If you get into trouble in the meantime, adding things back one-by-one often helps, and I hope you do not get into trouble!
## `"test-dependencies"` All the packages that you use in `tests/` with `elm-test` but not in the application you actually want to ship. This also uses exact versions to make tests more reliable. --- ### Elm.Json/Package # `elm.json` for packages This is roughly `elm.json` for the `elm/json` package: ```json { "type": "package", "name": "elm/json", "summary": "Encode and decode JSON values", "license": "BSD-3-Clause", "version": "1.0.0", "exposed-modules": [ "Json.Decode", "Json.Encode" ], "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { "elm/core": "1.0.0 <= v < 2.0.0" }, "test-dependencies": {} } ```
## `"type"` Either `"application"` or `"package"`. All the other fields are based on this choice.
## `"name"` The name of a GitHub repo like `"elm-lang/core"` or `"rtfeldman/elm-css"`. > **Note:** We currently only support GitHub repos to ensure that there are no author name collisions. This seems like a pretty tricky problem to solve in a pleasant way. For example, do we have to keep an author name registry and give them out as we see them? But if someone is the same person on two platforms? And how to make this all happen in a way this is really nice for typical Elm users? Etc. So adding other hosting endpoints is harder than it sounds.
## `"summary"` A short summary that will appear on [`package.elm-lang.org`](https://package.elm-lang.org/) that describes what the package is for. Must be under 80 characters.
## `"license"` An OSI approved SPDX code like `"BSD-3-Clause"` or `"MIT"`. These are the two most common licenses in the Elm ecosystem, and BSD-3-Clause is a good default. But you can see the full list of options [here](https://spdx.org/licenses/).
## `"version"` All packages start at `"1.0.0"` and from there, Elm automatically enforces semantic versioning by comparing API changes. So if you make a PATCH change and call `elm bump` it will update you to `"1.0.1"`. And if you then decide to remove a function (a MAJOR change) and call `elm bump` it will update you to `"2.0.0"`. Etc.
## `"exposed-modules"` A list of modules that will be exposed to people using your package. The order you list them will be the order they appear on [`package.elm-lang.org`](https://package.elm-lang.org/). **Note:** If you have five or more modules, you can use a labelled list like [this](https://github.com/elm-lang/core/blob/master/elm.json). We show the labels on the package website to help people sort through larger packages with distinct categories. Labels must be under 20 characters.
## `"elm-version"` The range of Elm compilers that work with your package. Right now `"0.19.0 <= v < 0.20.0"` is always what you want for this.
## `"dependencies"` A list of packages that you depend upon. In each application, there can only be one version of each package, so wide ranges are great. Fewer dependencies is even better though! > **Note:** Dependency ranges should only express _tested_ ranges. It is not nice to use optimistic ranges and end up causing build failures for your users down the line. Eventually we would like to have an automated system that tries to build and test packages as new packages come out. If it all works, we could send a PR to the author widening the range.
## `"test-dependencies"` Dependencies that are only used in the `tests/` directory by `elm test`. Values from these packages will not appear in any final build artifacts. --- ### README # Elm A delightful language for reliable webapps. Check out the [Home Page](https://elm-lang.org/), [Try Online](https://elm-lang.org/try), or [The Official Guide](https://guide.elm-lang.org/)
## Install ✨ [Install](https://guide.elm-lang.org/install/elm.html) ✨ For multiple versions, previous versions, and uninstallation, see the instructions [here](https://github.com/elm/compiler/blob/main/installers/README.md).
## Help If you are stuck, ask around on [the Elm slack channel][slack]. Folks are friendly and happy to help with questions! [slack]: https://elm-lang.org/community/slack ---