Crystal 0.30.0 has been released!
This release comes with some language changes, compiler features, and std-lib improvements. There is some work-in-progress related to multi-threading in other branches, they are moving forward and we are eager to share them as a whole.
There are 139 commits since 0.29.0 by 28 contributors.
Let’s review some highlights in this release. But don’t miss the rest of the release changelog which has a lot of valuable information.
Language changes
The language now checks that the return type of an abstract method is obeyed. This means that in an implementing type you need to annotate explicitly the return type if the abstract method is also annotated.
The following is now an error
abstract class Foo
abstract def foo : String
end
class Bar < Foo
def foo
1
end
end
You will need to declare Bar#foo
as def foo : String
which makes the underlying issue more evident: Bar#foo
was wrongly trying to return an Int32
instead of a String
.
You don’t need to copy and paste it. A subtype can be used.
class Parent; end
class Child < Parent; end
abstract class Foo
abstract def foo : Parent
end
class Bar < Foo
def foo : Child
Child.new
end
end
Finally, if you forget to implement some abstract method the compiler will let you know. Even on generic types and modules.
class Foo
include Enumerable(Int32)
end
In src/enumerable.cr:37:16
37 | abstract def each(&block : T -> _)
^---
Error: abstract `def Enumerable(T)#each(&block)` must be implemented by Foo
Since this change is likely to break a good amount of code it is introduced as a warning. Build your project with --warnings=all
to be ready for when this is switched from a warning to a real compile-time error. Read more about this feature in #7956, #7999, and #8010.
Syntax changes
A small breaking-change syntax wise is that ranges can not span across lines since #7888.
Macros
There are a couple of new macro methods to extract arguments of Annotations
in #7694. For all metaprogramming lovers, this would be good stuff. As usual, metaprogramming is not something to abuse.
The API to work with AST nodes of paths and types had some polishing that will bring some fewer headaches. Read more in #7970.
Compiler
Support for LLVM 7 was a long debt. We finally paid it together with support for LLVM 8. Read more about it in #7987 and #7986. In case you want to contribute in two months with the LLVM 9 support ;-)
There are a couple of bug-fixes related to top-level private const scope, annotation lookup on generic types and other corner cases.
Distribution
In case you missed the news, the nightly Linux release is available in snapstore.io and in TravisCI as crystal: nightly
in your travis.yml
. This was automated in #7893.
For macOS official packages (ie: the one that you can download from GitHub) we are now using LLVM 6.0.1. Don’t ask what has been used up until today.
For Homebrew, LLVM 8.0.0 is used from now on.
Standard library
There was a need for a breaking-change in UUID
: the method UUID#to_slice
was removed because it exposed a pointer to the underlying memory representation and doing that in a stack allocated value is error-prone. Use UUID#bytes
instead, that returns a StaticArray(UInt8, 16)
. Read more at #7901.
Boxing of values using Box
is used for some C callbacks and some low-level structures. Thanks to #8016 the boxing of nil
and reference types is now lighter.
Benchmark.memory
is now available to measure just memory usage. Read more at #7835.
Every now and then some sample code in the docs are outdated. There is a tool made and run regularly to keep them in good shape. Luckily #8003 was not as big as other past iteration. Check maiha/crystal-examples to see how this is done!
Serialization
JSON serialization can handle numeric keys, so Hash(Int32, String).from_json
works. Read more at #7944.
YAML deserialization handles String
as the last option if the expected type is a union. Since anything can be a String
that make sense. Read more at #7938
Finally there is a breaking-change regarding the API on the JSON parser. The usage of symbols for the parser state was replaced by enums in #7966.
Networking
URI.escape
and URI.unescape
are deprecated and you will need to choose between URI.encode_www_form
/URI.decode_www_form
and URI.encode
/URI.decode
. This allows you to choose how to handle reserved chars. Read more at #7997.
The parsing of the HTTP protocol got some performance optimizations in #8002 and #8009. This might improve the performance of HTTP::Server
in your apps.
System
There is an initial API to work with users and groups in System::User
and System::Group
. Read more at #7725.
Other news
Snapcraft 3.7 has been released and that means that the Crystal plugin can be used out of the box.
Next steps
Please update your Crystal and report any issues. We will keep moving forward and start the development focusing on 0.31.
Once again, check your code with --warnings=all
. This will help in the migration of your codebase and will probably push some feedback about that tool. Some future language changes were introduced in this release as warnings for a smooth migration. But, unless you use --warnings=all
you will not discover them.
It will also be helpful if your shards are run against Crystal nightly releases. Either Docker or Snap are the current channels to get them easily. This will help to reduce the friction of a release while checking if the ecosystem is in good shape.
Stay tuned!
The development is possible thanks to the community’s effort, 84codes’ support, and every supporter.