Note: we're starting with a new release approach. Each time a breaking change happens, the alpha number will be incremented in 0.0.0-alpha. The * indicates a rolling release, the tar.gz archives in assets will be updated if the changes are non-breaking. So upgrading to the latest tar.gz with the same alpha should not create any problems.
We recommend these alpha releases for most users instead of the nightly releases.
:exclamation: if your project used a latest nightly url like:
Run roc format --migrate to upgrade most syntax changes
Replace usages of Task with effectful! functions
Use Result.map_ok instead of Result.map
Str.BadUtf8 has changed from BadUtf8 Utf8ByteProblem U64 to BadUtf8 { problem: Utf8Problem, index: U64}
What changed?
Since the last update, Roc has gone through lots of syntax changes! We want
to make Roc a friendly language for new programmers, functional programming wizards,
and everyone in between. To that end, we've made Roc look more like mainstream
languages while still keeping things clean and concise.
Let's look at a sample application to see what changed:
This example reads the README and the LICENSE of a repository and prints some info on
it, namely the first line of the README and the number of lines in the LICENSE. Let's
look at its modern counterpart!
Lots has changed, even if it works the same under the hood! Let's list the changes:
Functions get called with ( and ) now instead of whitespace (also tags like Ok(val) instead of Ok val)
Function arguments are now surrounded with | pipes, just like Rust or Ruby
All variable and function names are in snake_case instead of camelCase, which makes individual words in variables easier to read
Functions that might have side effects (like writing to a file) must have a ! at the end of their name, which means ! is no longer an operator but just a suffix
String interpolation now uses ${ and } instead of $( and )
We now use and and or for boolean operators instead of the old && and || operators to make them distinct from the new |args| function syntax
In addition to the stylistic changes, there are some additional syntax features for error handling:
? right after an expression that returns a Result will either early return the Err or unwrap the Ok value, just like Rust
If you put a space between the expression and ?, it will use the function after the ? to map the Err value first before the early return happens
This is really useful for giving additional useful for giving context
?? unwraps a Result with a default value just like Result.with_default(), but with the benefit of only calculating the provided default expression if necessary
Most of the work to change existing Roc code to the new format can be done for you by the Roc compiler; just run
$ roc format --migrate
and the above stylistic changes will get converted for you. The main thing you'll have to do is replace any usage of Task with an effectful function, AKA one with a ! at the end of its name. Task has now been completely removed from Roc, which we think is a great improvement to the simplicity and readability of Roc. Also, Result.map has been renamed to Result.map_ok for better compatability with future plans for Roc.
This has been a whirlwind of changes! Don't worry, our hope has been to do the majority of the changes needed for Roc to look how it will in the long-term, so you won't have to do much migration after this feature push.
Some other APIs we've changed/added:
Renamed Result.map with Result.map_ok
Introduce some new Str operations:
Str.with_ascii_lowercased: make ASCII characters in a string lowercase and leave everything else the same
Str.with_ascii_uppercased: make ASCII characters in a string uppercase and leave everything else the same
Str.caseless_ascii_equals: compare the contents of two strings, ignoring case for ASCII characters
Str.from_utf8: convert a List U16 to a string, failing on invalid codepoints
We already had this, but it changed error types:
Old: from_utf8 : List U8 -> Result Str [BadUtf8 Utf8ByteProblem U64]
New: from_utf8 : List U8 -> Result Str [BadUtf8 { problem : Utf8Problem, index : U64 }]
Str.from_utf8_lossy: convert a List U8 to a string, replacing invalid codepoints with the "�" character
Str.from_utf16: convert a List U16 to a string, failing on invalid codepoints
Str.from_utf16_lossy: convert a List U16 to a string, replacing invalid codepoints with the "�" character
Str.from_utf32: convert a List U16 to a string, failing on invalid codepoints
Str.from_utf32_lossy: convert a List U32 to a string, replacing invalid codepoints with the "�" character
Added some effectful List walking functions:
for_each!: Run an effectful operation on every element in a list
for_each_try!: Run an effectful operation on every element in a list, returning early on an Err
walk!: Effectfully walk through the elements of a list, building up state as you go
walk_try!: Effectfully walk through the elements of a list, building up state as you go, returning early on an Err
That's it for now! Let us know if you run into any issues in the Zulip chat, we're here to help!