-
-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
31cea6f
commit 23a9ec1
Showing
1 changed file
with
272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
--- | ||
title: Crystal 1.14.0 is released! | ||
version: 1.14.0 | ||
date: 2024-10-09 | ||
author: straight-shoota | ||
--- | ||
We are announcing a new Crystal release with several new features and bug fixes. | ||
|
||
Pre-built packages are available on [GitHub Releases](https://github.com/crystal-lang/crystal/releases/tag/1.14.0) | ||
and our official distribution channels. | ||
See [crystal-lang.org/install](https://crystal-lang.org/install/) for | ||
installation instructions. | ||
|
||
## Stats | ||
|
||
This release includes [134 changes since 1.13.3](https://github.com/crystal-lang/crystal/pulls?q=is%3Apr+milestone%3A1.14.0) | ||
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](/2024/02/09/84codes-manas-mt) 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](https://forum.crystal-lang.org/t/new-event-loop-unix-call-for-reviews-tests/7207) | ||
for a heads up. | ||
|
||
The upcoming execution contexts API from [RFC 2](https://github.com/crystal-lang/rfcs/pull/2) is available as a standalone shard for testing: | ||
[`ysbaddaden/execution_context`](https://github.com/ysbaddaden/execution_context). | ||
|
||
## Changes | ||
|
||
Below we list the most remarkable changes in the language, compiler and stdlib. | ||
For more details, visit the [full changelog](https://github.com/crystal-lang/crystal/releases/tag/1.14.0). | ||
|
||
### Breaking | ||
|
||
⚠️ [`Slice#[start, count]`][slice_accessor] 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]). | ||
|
||
[slice_accessor]: https://crystal-lang.org/api/1.14.0/Slice.html#%5B%5D%28start%3AInt%2Ccount%3AInt%29%3ASlice%28T%29-instance-method | ||
[#14778]: https://github.com/crystal-lang/crystal/pull/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]). | ||
|
||
[`Socket`]: https://crystal-lang.org/api/1.14.0/Socket.html | ||
[`IO::FileDescriptor`]: https://crystal-lang.org/api/1.14.0/IO/FileDescriptor.html | ||
[#14882]: https://github.com/crystal-lang/crystal/pull/14882 | ||
|
||
⚠️ [`XML::Error.errors`] had been deprecated since [1.7.0](/_releases/2023-01-09-1.7.0-released.md), 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]). | ||
|
||
[`XML::Error.errors`]: https://crystal-lang.org/api/1.14.0/XML/Error.html#errors:Array(XML::Error)|Nil-class-method | ||
[#14936]: https://github.com/crystal-lang/crystal/pull/14936 | ||
|
||
⚠️ `Hash::Entry` has been removed from public API docs. It was never intended to be a public type. ([#14881]). | ||
|
||
[#14881]: https://github.com/crystal-lang/crystal/pull/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]* | ||
|
||
[#14951]: https://github.com/crystal-lang/crystal/pull/14951 | ||
|
||
`HashLiteral` and `NamedTupleLiteral` respond to `#has_key?`, just like their regular counterparts `Hash` and `NamedTuple` ([#14890]). | ||
|
||
*Thanks [@kamil-gwozdz]* | ||
|
||
[#14890]: https://github.com/crystal-lang/crystal/pull/14890 | ||
|
||
### Standard library | ||
|
||
The [`WaitGroup`] concurrency primitive gains some convenience methods, | ||
[`WaitGroup.wait`] and [`WaitGroup#spawn`] ([#14837]). | ||
|
||
```crystal | ||
require "wait_group" | ||
WaitGroup.wait do |wg| | ||
10.times do | ||
wg.spawn do | ||
sleep 5.seconds | ||
end | ||
end | ||
end | ||
``` | ||
|
||
*Thanks [@jgaskins]* | ||
|
||
[`WaitGroup`]: https://crystal-lang.org/api/1.14.0/WaitGroup.html | ||
[`WaitGroup.wait`]: https://crystal-lang.org/api/1.14.0/WaitGroup.html#wait%3ANil-instance-method | ||
[`WaitGroup#spawn`]: https://crystal-lang.org/api/1.14.0/WaitGroup.html#spawn%28%26block%29%3AFiber-instance-method | ||
[#14837]: https://github.com/crystal-lang/crystal/pull/14837 | ||
|
||
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. | ||
|
||
[`Slice#same?`]: https://crystal-lang.org/api/1.14.0/Slice.html#same?(other:self):Bool-instance-method | ||
[`Pointer::Appender#to_slice`]: https://crystal-lang.org/api/1.14.0/Pointer/Appender.html#to_slice:Slice(T)-instance-method | ||
[#14728]: https://github.com/crystal-lang/crystal/pull/14728 | ||
[#14874]: https://github.com/crystal-lang/crystal/pull/14874 | ||
|
||
*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]* | ||
|
||
[#14891]: https://github.com/crystal-lang/crystal/pull/14891 | ||
|
||
### 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]* | ||
|
||
[#14911]: https://github.com/crystal-lang/crystal/pull/14911 | ||
[#14921]: https://github.com/crystal-lang/crystal/pull/14921 | ||
[#14940]: https://github.com/crystal-lang/crystal/pull/14940 | ||
[#14958]: https://github.com/crystal-lang/crystal/pull/14958 | ||
[#14941]: https://github.com/crystal-lang/crystal/pull/14941 | ||
[#14943]: https://github.com/crystal-lang/crystal/pull/14943 | ||
[#14947]: https://github.com/crystal-lang/crystal/pull/14947 | ||
[#14979]: https://github.com/crystal-lang/crystal/pull/14979 | ||
[#14933]: https://github.com/crystal-lang/crystal/pull/14933 | ||
[#14945]: https://github.com/crystal-lang/crystal/pull/14945 | ||
[#14964]: https://github.com/crystal-lang/crystal/pull/14964 | ||
[#12495]: https://github.com/crystal-lang/crystal/issues/12495 | ||
|
||
### `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]). | ||
|
||
```crystal | ||
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" | ||
``` | ||
|
||
[`URI::Params::Serializable`]: https://crystal-lang.org/api/1.14.0/URI/Params/Serializable.html | ||
|
||
*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]* | ||
|
||
[`URI.from_json_object_key?`]: https://crystal-lang.org/api/1.14.0/URI.html#from_json_object_key%3F%28key%3AString%29%3AURI%7CNil-class-method | ||
|
||
[#14834]: https://github.com/crystal-lang/crystal/pull/14834 | ||
[#14684]: https://github.com/crystal-lang/crystal/pull/14684 | ||
|
||
### 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]* | ||
|
||
[#14953]: https://github.com/crystal-lang/crystal/pull/14953 | ||
|
||
### Performance | ||
|
||
This release includes some minor performance improvements, particularly in the | ||
compiler ([#14748], [#14992], [#15002]). | ||
|
||
*Thanks [@ysbaddaden], [@HertzDevil], [@ggiraldez]* | ||
|
||
[#15002]: https://github.com/crystal-lang/crystal/pull/15002 | ||
[#14992]: https://github.com/crystal-lang/crystal/pull/14992 | ||
[#14748]: https://github.com/crystal-lang/crystal/pull/14748 | ||
|
||
### 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]* | ||
|
||
[#14842]: https://github.com/crystal-lang/crystal/pull/14842 | ||
[#14872]: https://github.com/crystal-lang/crystal/pull/14872 | ||
[#14997]: https://github.com/crystal-lang/crystal/pull/14997 | ||
|
||
## 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]* | ||
|
||
[`Pointer.new(Int)`]: https://crystal-lang.org/api/1.14.0/Pointer.html#new(address:Int)-class-method | ||
[#14875]: https://github.com/crystal-lang/crystal/pull/14875 | ||
|
||
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]* | ||
|
||
[#14805]: https://github.com/crystal-lang/crystal/pull/14805 | ||
[#14962]: https://github.com/crystal-lang/crystal/pull/14962 | ||
[`Benchmark.ips`]: https://crystal-lang.org/api/1.14.0/Benchmark.html#ips%28calculation%3ATime%3A%3ASpan%3D5.seconds%2Cwarmup%3ATime%3A%3ASpan%3D2.seconds%2Cinteractive%3ABool%3DSTDOUT.tty%3F%2C%26%29-instance-method | ||
[`::sleep`]: https://crystal-lang.org/api/1.14.0/toplevel.html#sleep%28time%3ATime%3A%3ASpan%29%3ANil-class-method | ||
[`Time::Span`]: https://crystal-lang.org/api/1.14.0/Time/Span.html | ||
[`Int#seconds`]: https://crystal-lang.org/api/1.14.0/Int.html#seconds:Time::Span-instance-method | ||
--- | ||
|
||
> **THANKS:** | ||
> We have been able to do all of this thanks to the continued support of [84codes](https://www.84codes.com/) and every other [sponsor](/sponsors). | ||
> To maintain and increase the development pace, donations and sponsorships are | ||
> essential. [OpenCollective](https://opencollective.com/crystal-lang) is | ||
> available for that. | ||
> | ||
> Reach out to [[email protected]](mailto:[email protected]) | ||
> if you’d like to become a direct sponsor or find other ways to support Crystal. | ||
> We thank you in advance! | ||
[@bcardiff]: https://github.com/bcardiff | ||
[@Blacksmoke16]: https://github.com/Blacksmoke16 | ||
[@ggiraldez]: https://github.com/ggiraldez | ||
[@HertzDevil]: https://github.com/HertzDevil | ||
[@jgaskins]: https://github.com/jgaskins | ||
[@kamil-gwozdz]: https://github.com/kamil-gwozdz | ||
[@kojix2]: https://github.com/kojix2 | ||
[@nobodywasishere]: https://github.com/nobodywasishere | ||
[@straight-shoota]: https://github.com/straight-shoota | ||
[@ysbaddaden]: https://github.com/ysbaddaden | ||
[84codes]: https://www.84codes.com/ |