Crystal 1.14.0 is released!
We are announcing a new Crystal release 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 134 changes since 1.13.3 by 13 contributors. We thank all the contributors for all the effort put into improving the language! ❤️
Advances in multi-threading support
The project to improve multi-threading support with the help of 84codes is still ongoing. This release doesn’t include any big changes. There are a couple of smaller concurrency improvements, though.
We expect to roll out a major performance upgrade to the event loop for the 1.15 development cycle. See New Event Loop (UNIX): call for reviews & tests for a heads up.
The upcoming execution contexts API from RFC 2 is available as a standalone shard for testing:
ysbaddaden/execution_context
.
Changes
Below we list the most remarkable changes in the language, compiler and stdlib. For more details, visit the full changelog.
Breaking
⚠️ Slice#[start, count]
now accepts a negative index for start
, like similar methods already do.
This would break existing code that depends on the current behaviour that a negative start index raises IndexError
(#14778).
⚠️ Finalizers for Socket
and IO::FileDescriptor
do no longer flush.
We realized that flushing is too heavy for a finalizer, as it might involve the event loop and even memory allocations which must be strictly avoided in a finalizer.
Be sure to always flush before letting a stream go out of scope, ideally with an explicit #close
(#14882).
⚠️ XML::Error.errors
had been deprecated since 1.7.0, but continued to work.
This unconditioned availability causes a serious memory leak, which cannot be fixed without disabling XML::Error.errors
.
In order to make this obvious, calling the method causes a compile time error now. (#14936).
⚠️ Hash::Entry
has been removed from public API docs. It was never intended to be a public type. (#14881).
Thanks @ysbaddaden, @straight-shoota and @Blacksmoke16
Language features
Allow ^
in constant numeric expressions (#14951). This operator was oddly missing even though |
and &
were already supported.
Thanks @HertzDevil
HashLiteral
and NamedTupleLiteral
respond to #has_key?
, just like their regular counterparts Hash
and NamedTuple
(#14890).
Thanks @kamil-gwozdz
Standard library
The WaitGroup
concurrency primitive gains some convenience methods,
WaitGroup.wait
and WaitGroup#spawn
(#14837).
require "wait_group"
WaitGroup.wait do |wg|
10.times do
wg.spawn do
sleep 5.seconds
end
end
end
Thanks @jgaskins
There are two new methods for working with slices: Slice#same?
checks
if two slices point to the same memory (#14728).
And Pointer::Appender#to_slice
(#14874) makes it easy to create a slice
containing the items from an appender.
Thanks @straight-shoota
A minor fix turning an eager class getter into a lazy one avoids linking libpcre
for programs that do not use Regex
(#14891).
Thanks @kojix2
Windows
Windows support is making good progress.
The interpreter runs on Windows (#14964). There is still a limitation: networking does not work due to #12495.
And the compiler can now target ARM64 Windows, i.e. aarch64-windows-msvc
.
It’s not 100% polished, but looking pretty well. Read #14911 for details on how to test it out.
Currently we still need to cross-compile because the compiler itself does not run on ARM64 Windows yet.
Starting with this release, DNS requests resolve asynchronously on Windows (#14979). It’s actually the first platform to support that.
There are also a number of improvements regarding non-blocking IO:
- Support non-blocking
File#read
and#write
(#14940),File#read_at
(#14958),Process.run
standard streams (#14941),IO::FileDescriptor#flock_*
(#14943). - Emulate non-blocking
STDIN
console (#14947). - Open non-blocking regular files as overlapped (#14921).
And we add implementations of System::User
(#14933) and System::Group
on Windows (#14945).
Thanks @HertzDevil
URI::Params
URI::Params::Serializable
is a new serialization API which works similar to
the JSON and YAML variants, but for the URI query parameters format (#14684).
require "uri/params/serializable"
record Applicant,
first_name : String
last_name : String
qualities : Array(String) do
include URI::Params::Serializable
end
applicant = Applicant.from_www_form "first_name=John&last_name=Doe&qualities=kind&qualities=smart"
applicant # => Applicant(@first_name="John", @last_name="Doe", @qualities=["kind", "smart"])
applicant.to_www_form # => "first_name=John&last_name=Doe&qualities=kind&qualities=smart"
Thanks @Blacksmoke16
In a related matter, URI
is now applicable as a key in JSON objects via URI.from_json_object_key?
(#14834).
Thanks @nobodywasishere
Compiler tools
The compiler binary can now execute external programs as subcommands:
crystal foo
tries to run crystal-foo
if foo
is not an internal command.
This allows us to split the compiler binary into separate executables which helps
improve iteration speed (#14953).
Thanks @bcardiff
Performance
This release includes some minor performance improvements, particularly in the compiler (#14748, #14992, #15002).
Thanks @ysbaddaden, @HertzDevil, @ggiraldez
Dependency Updates
LibCrypto
bindings now support LibreSSL 3.5+ (#14872).- Support for Unicode 16.0.0 (#14997).
- Support for LLVM 19.1 (#14842)
Thanks @straight-shoota, @HertzDevil
Deprecations
Pointer.new(Int)
was deprecated in favour of Pointer.new(UInt64)
(#14875).
Deprecation warnings for argument type that autocast to UInt64
can be ignored
or disabled by explicitly casting to UInt64
.
Thanks @straight-shoota
We updated a couple of APIs that receive a time span argument.
Benchmark.ips
(#14805) and ::sleep
(#14962) now explicitly require
Time::Span
. The overloads with Number
are deprecated.
You can convert bare numbers with Int#seconds
to use the valid overload.
Thanks @HertzDevil
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!
Contribute