Crystal 1.16.0 is released!
We are announcing a new Crystal release 1.16.0 with several new features and bug fixes.
Pre-built packages are available on GitHub Releases and our official distribution channels. See crystal-lang.org/install for installation instructions.
Stats
This release includes 162 changes since 1.15.1 by 19 contributors. We thank all the contributors for all the effort put into improving the language! ❤️
Changes
Below we list the most remarkable changes in the language, compiler and stdlib. For more details, visit the full changelog.
Breaking
The following changes break prior behavior of the compiler, but we expect them to not break much in existing code. If this is not the case, please let us know in the issue tracker or forum.
Fixed implementation of File.match?
The implementation of File.match?
was insufficient and has been replaced by a new algorithm.
This change should not affect any behaviour that was previously working as documented.
The correction of implementation bugs leads to the following changes in observed behaviour:
- Wildcard and globstar are able to match non-greedily. For example,
**/a
now matchesa
. - Globstar matches full path segments only, otherwise it’s just two wildcards (which is equivalent to a single one). For example,
a**
no longer matchesab/c
(but it matchesab
). - Subpatterns in branches are parsed with respect to their respective syntactical context. For example,
{[}]}
now matches}
. It parses as a branch with one subpattern that describes the character set}
. Previously, this was a parse error. - Escapes for special character are recognized. For example,
\\t
now matches\t
while previously it matchedt
. - The grammar for parsing character classes is more flexible. For example,
[a-]
, now matchesa
and-
. Previously, it was a pattern error (incomplete character range).
Note: Dir.glob
is implemented differently and is not affected by that invalid behaviour. There were no changes to it.
Thanks, @straight-shoota
Parameter name suffixes are deprecated
The suffixes ?
and !
for parameter names of defs, macros and blocks are deprecated. This aligns them with other variable names. They produce a warning now (#12197).
Thanks, @potomak
Implicit return type of Enumerable#sum
and #product
Enumerable#sum
and #product
no longer resolve an implicit return type when the element type is a union. This can’t work reliably.
Instead, you need to specify the sum/product type explicitly by the initial
parameter with a value of the intended return type (#15314).
In effect, this moves a runtime error condition to a compile time error.
# Crystal 1.16.0
[1, 10000000000_u64].sum # Error: `Enumerable#sum` and `#product` do not support Union types.
# Instead, use `Enumerable#sum(initial)` and `#product(initial)`,
# respectively, with an initial value of the intended type of the call.
# Crystal < 1.16.0
[1, 10000000000_u64].sum # OverflowError: Arithmetic overflow
# Passing an explicit initial value works, before and after:
[1, 10000000000_u64].sum(0_u64) # => 10000000001_u64
Thanks, @rvprasad
Resource string in HTTP::Request
HTTP::Request
was fixed to correctly parse HTTP resource strings that look like an absolute URL.
This may break code that relied on the previous, buggy behaviour (#15499).
# Crystal 1.16.0
HTTP::Request.new("GET", "http://example.com/foo").path # => "http://example.com/foo"
# Crystal < 1.16.0
HTTP::Request.new("GET", "http://example.com/foo").path # => "/foo"
Thanks, @straight-shoota
Environment changes for subcommands
The compiler won’t set the environment variable $CRYSTAL
when running a process for a subcommand.
This variable was only in introduced in #14953 in 1.14.0.
We addded a more flexible alternative $CRYSTAL_EXEC_PATH
, and the equivalent to $CRYSTAL
is now $CRYSTAL_EXEC_PATH/crystal
. The compiler also prepends its path to $PATH
(#15186).
Thanks, @straight-shoota
Execution Contexts
Execution contexts from RFC 0002 are available as a preview feature. It has already proven to be quite robust, but there might be some rough edges.
You can test execution contexts with the compiler flags -Dpreview_mt -Dexecution_context
.
The default context is single threaded (unlike standalone -Dpreview_mt
).
But you can then start additional contexts as you need (for example, a Fiber::ExecutionContext::MultiThreaded
or Fiber::ExecutionContext::Isolated
).
mt_context = Fiber::ExecutionContext::MultiThreaded.new("worker-threads", 4)
10.times do
mt_context.spawn do
do_something
end
end
gtk = Fiber::ExecutionContext::Isolated.new("Gtk") do
Gtk.main
end
gtk.wait
Execution contexts are supported on most targets, including, Linux, macOS, Windows and the different BSDs, on X86 and ARM architectures. This addition marks the peak of the ongoing project to improve multi-threading support with the help of 84codes.
Language
Slice.literal
can infer the element type (#15529) and works in the interpreter (#15531).
Thanks, @HertzDevil
Thanks, @HertzDevil
Standard library
- Several bug fixes and performance improvements to
Path
handling, especially for Windows paths.
Thanks, @HertzDevil
- New methods
Indexable#find
and#find!
(#15552).
Thanks, @punteek
- New methods
EventLoop#wait_readable
,#wait_writable
(#15376).
Thanks, @ysbaddaden
Compiler
- The compiler CLI understand the long option
--output
everywhere, instead of just the short variant-o
(#15519). It also accepts a directory name as value, in which case the file name is derived from the source filename (#15471).
Thanks, @HertzDevil, @straight-shoota
- The compiler respects the environment variable
$MACOSX_DEPLOYMENT_TARGET
, which gets rid of annoying linker warnings when target versions are mismatched (#15603)
Thanks, @HertzDevil
Compiler tools
The doc generator can optionally include private
and protected
objects as well as objects in lib bindings (lib
, fun
, union
, cstruct
, external
, and type
), as proposed in RFC 0011. The :showdoc:
directive enables that.
# :showdoc:
#
# Documentation for LibFoo
lib Foo
# Documentation for function foo
fun foo : Void
end
# :showdoc:
#
# Documentation for method bar
private def bar
end
Thanks @nobodywasishere
Dependency Updates
- Support for LLVM 20 (#15412)
Thanks, @HertzDevil
Deprecations
LLVM::ABI
(andLLVM::TargetMachine#abi
) is deprecated without replacement (#15227).
We have been able to do all of this thanks to the continued support of 84codes and every other sponsor. To maintain and increase the development pace, donations and sponsorships are essential. OpenCollective is available for that.
Reach out to crystal@manas.tech if you’d like to become a direct sponsor or find other ways to support Crystal. We thank you in advance!
ContributeDiscussions on the web
- Crystal 1.16.0 () on HackerNews (102 points · 29 comments)