Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.14.0 #843

Merged
merged 15 commits into from
Oct 9, 2024
272 changes: 272 additions & 0 deletions _releases/2024-10-09-1.14.0-released.md
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/