Skip to content

Instantly share code, notes, and snippets.

@evancz

evancz/alpha.md Secret

Last active September 26, 2019 12:04
Show Gist options
  • Star 53 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evancz/8e89512dfa9f68903f05f1ac4c44861b to your computer and use it in GitHub Desktop.
Save evancz/8e89512dfa9f68903f05f1ac4c44861b to your computer and use it in GitHub Desktop.
NOT FOR SHARING

NOT FOR SHARING. Do not post on reddit, twitter, HN, discourse, etc. Learn why here.


Elm 0.19 Alpha

Hello! I am pretty nervous about sharing this alpha. I am really happy with the work, but I also feel increasingly beleaguered by online interactions. So I guess I just want to say that I worked really hard, and I am excited to share my work with people who like Elm. There may be things that are broken or decisions that you do not like, but I hope we can work through it in a friendly way, knowing that the goal is a great release!

Goals for the alpha:

  • Update packages
  • Update editor plugins
  • Report any odd, unexpected, or broken behavior on the #elm-dev slack channel

Most people will not be testing 0.19 and should not be disrupted by any of our work. Anything public facing should change after the testing period is over.

Timeline: We will have one month (minimum) before the actual release. Could be longer depending on how things go!




Guidelines

Here are some guidelines for making this testing period fun and effective.


Blogging DURING the alpha.
I really want to be able to present 0.19 outside the Elm community in my own words. I think this is really important strategically (as I described here) and I think it would really hurt Elm for so many months of work to end with messy public communication.

Blogging AFTER the release.
This would be great! I would personally love to hear stories about build times going down, the upgrade process, interesting refactoring stories, etc.


Opening GitHub issues.
This would be really hard to track and make it harder to process everything.

Talking in #elm-dev on Slack.
I suspect many things can be resolved just by talking. So still make an SSCCE, but share the code in #elm-dev instead! We will have folks go through chat logs and bump things to issues if needed.


Running 0.19 in production.
Things may still change, there may be bugs, etc. So I think it is too risky, and I very strongly discourage it.

Trying 0.19 on personal projects.
Do things work? Do you notice any performance improvements? Regressions? Mention it in #elm-dev!





Binaries

Did you jump straight here? Please read the stuff above first!

These are just binaries. I recommend copying them into whatever directory you want to work in. This way it will not mess with your PATH or stop you from working with 0.18 in the meantime.


Packages

Temporary package server: https://alpha.elm-lang.org/

All the binaries point to this server. So if you publish, it goes here, not to package.elm-lang.org. I will shut this temporary server down before the final release, so it is safe to make mistakes in the testing period!

You need to tag with git tag -a rc1-X.Y.Z -m "whatever" in the testing period. (Running elm publish will tell you this as well!) The idea is that these should be temporary as you work through things. After the final release, you will need to republish under X.Y.Z.




Upgrade Instructions

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.19.

Note: You can try out 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.


Command Line

There is now just one elm binary at the command line. The terminal commands are now:

# 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:

Both are quite similar to the elm-package.json format, and elm-upgrade can help you with this.


Changes

Functions Changed

Modules Moved

  • Json.Encode and Json.Decode moved to elm/json
  • Time and Date moved to elm/time with a significantly improved API
  • Random moved to elm/random with a better implementation and a few new functions
  • Regex moved to elm/regex with a much clearer README

Packages Moved

  • elm-lang/* moved to elm/*
  • evancz/url-parser moved to elm/url with a simpler and more flexible API
  • elm-tools/elm-parser moved to elm/parser with speed boost when compiling with the --optimize flag
  • elm/browser 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
    • 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, and I would really love to know the before-and-after on build times of any projects you upgrade to 0.19. I think this could help make the blog post announcing things stronger. So please share the results of the following commands in #elm-dev slack and I can start collecting it into a table!

  • 0.18 - rm -rf elm-stuff/build-artifacts ; time elm-make Thing.elm
  • 0.19 - rm -rf elm-stuff ; rm ~/.elm/0.19.0/package/*/*/*/*.dat ; time elm make Thing.elm

Be sure that you are not downloading packages in any of these cases! Get that done first, then run these!

Note: The point is to just race the compilers against each other. Neither scenario is realistic, but by making sure "the same amount of code" is compiled, we can try to figure out the speed difference itself. The caching is a cool extra on top of that.


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:

(|-~->) : (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.


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.
@evancz
Copy link
Author

evancz commented May 8, 2018

Please share comments in #elm-dev on slack instead of in comments here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment