Skip to content
GitHub Repository Forum RSS-Newsfeed

Crystal 1.21.0 is released!

Johannes Müller

We are announcing a new Crystal release 1.21.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.

This release includes 161 changes since 1.20.3 by 21 contributors. We thank all the contributors for all the effort put into improving the language! ❤️

Below we list the most remarkable changes in the language, compiler, and stdlib. For more details, visit the full changelog.

We expect little disruption from the introduction of execution contexts. But it can break code with specific expectations about concurrent behaviour, especially about the fact that a fiber stays on the same thread. Read more about this in the next section.

Another breaking change is that we disabled the automatic fallback to legacy PCRE, which has been deprecated for many years now. You can still explicitly opt-in with compiler flag -Duse_pcre or environment variable USE_PCRE1=1 (#16924).

Thanks, @straight-shoota

If you notice any unexpected issues, please let us know in the issue tracker or forum.

Execution contexts from RFC 0002 are enabled by default. We have written an entire blog post about it: Releasing Execution Contexts.

The default context has parallelism 1, i.e. it is single-threaded. It can be explicitly resized to run multiple fibers in parallel, or you can create additional contexts for parallelism.

As a result, fibers are no longer pinned to one thread. Even with parallelism 1, fibers may switch threads. The only guarantee is that no more than one fiber runs at any time. Code that relies on thread-local state across fiber yields should be reviewed.

The concrete breaking changes are:

  1. Fibers in parallel execution contexts can resume in a different thread.
  2. Fibers in concurrent execution contexts can switch threads on a blocking syscall.
  3. Execution contexts don’t support spawn(same_thread:). In a parallel execution context, same_thread: true raises at runtime.

See Releasing Execution Contexts: Breaking Changes for details.

This effort is part of the ongoing project to improve multi-threading support with the help of 84codes.

Thanks @ysbaddaden

Percent string array literal with interpolation

Section titled Percent string array literal with interpolation

RFC 0021 introduces %W, a string array literal that complements %w with escape sequences and interpolation, including splats (#16919).

%W[foo\ bar baz] # => ["foo bar", "baz"]

%W[foo #{"bar"} baz]            # => ["foo", "bar", "baz"]
%W[foo #{1 + 1} baz]            # => ["foo", "2", "baz"]
%W[foo #{"bar"}baz#{"bab"} qux] # => ["foo", "barbazbab", "qux"]
%W[foo _#{"bar"}_ baz]          # => ["foo", "_bar_", "baz"]
%W[foo #{"bar baz"} qux]        # => ["foo", "bar baz", "qux"]

%W[foo #{*%w[bar baz]} qux] # => ["foo", "bar", "baz", "qux"]

Thanks, @straight-shoota

Socket#sendfile (and Crystal::EventLoop::Socket#sendfile) enables efficient file-to-socket transfer paths with fewer user-space copies (#16665).

File.open("foo/bar") do |file|
  socket.sendfile(file)
end

Thanks, @ysbaddaden

  • Branches in case expressions with multiple type expressions now split into separate restrictions for each type (#17072). case x; when Bar, Baz is now equivalent to if x.is_a?(Bar) elsif x.is_a?(Baz). Previously, it was equivalent to if x.is_a?(Bar | Baz). The latter can still be expressed as when Bar | Baz.

    Thanks, @straight-shoota

  • Improved debug metadata for procs (#16830), constants and class vars (#16831), and LLDB collection formatters (#16832) for better inspection and clearer debugger output.

    Thanks, @skuznetsov

  • ASTNode#inspect now prints an unambiguous representation of the syntax node and its properties, instead of folding into the source representation (#16699).

    Thanks, @straight-shoota

Thanks, @straight-shoota

Thanks, @straight-shoota, @ysbaddaden

Since 1.16, we’ve split the historic single manpage crystal(1) into individual pages for each subcommand. Now we’ve removed the original manpage from the repository. Manpage consumers must use the split manpages now.

We only provide the adoc sources, and package build scripts need to generate the roff format themselves (requires asciidoctor).

Package maintainers who ship manpages should update to the new build instructions if they haven’t already.

  • Makefile: Build manpages for install target (#16991)

Thanks, @straight-shoota


Thanks

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