Skip to content
GitHub Repository Forum RSS-Newsfeed

Crystal 1.13.0 is released!

Johannes Müller

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 180 changes since 1.12.2 by 25 contributors. We thank all the contributors for all the effort put into improving the language! ❤️

Advances in multi-threading support

As part of the project to improve multi-threading support with the help of 84codes, this release includes several improvements and refactors related to concurrency and the event loop. So far, these have been mostly internal changes with minor relevance from a user’s point of view. We expect more significant changes in the next release.

A preview of the upcoming execution context (RFC) is available as a standalone shard: ysbaddaden/execution_context. It’s available for testing by eager developers. This library is expected to be part of the compiler once we are certain it’s ready. We’re still ironing it, so bugs are expected, and reports very much welcomed!

Changes

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

Breaking

  • Never raise IndexError in #[]?(Range) (#14444).

    Thanks @HertzDevil

  • Fixed Set#to_a(&) (#14519).

    Thanks @meatball133

  • Restore leading zero in exponent for printf("%e") and printf("%g") (#14695). This fixes a regression introduced in Crystal 1.11.0.

    Thanks @straight-shoota

  • Implicit execution of batch files (.bat, .com) in Process.run on Windows was disabled as a safety measure (#14557).

    Thanks @straight-shoota

  • The module IO::Evented was removed from the public API docs ([#14749]). It is an internal implementation detail and was erroneously exposed in the docs.

    Thanks @straight-shoota

  • The CRYSTAL_LIBRARY_RPATH compiler config and delay-load helper have been removed (#14598). They were an only partially functional attempt for dynamic linking on Windows, now superseded by a more robust solution to actually install DLLs via @[Link] annotation.

    Thanks @HertzDevil

OpenSSL Default Configuration

The OpenSSL bindings previously included some explicit overrides for the default settings of the SSL library. This can be useful to improve the security level when working with older library versions. But it has the opposite effect with newer library versions and hinders the application of more restrictive default configurations. We removed overrides for cipher suites (#14655) and ECDH curve (#14656). The TLS Server compatibility level recommendations from Mozilla are deprecated as well. They didn’t even work correctly before (#14657). OpenSSL now uses the default configuration of the SSL library. Explicit overrides in user code are still possible of course.

Thanks @ysbaddaden

Rescue module types

Exception matching in rescue now supports module types in the type restriction.

module ErrorModule; end

class SomeError < Exception
  include ErrorModule
end

begin
  raise SomeError.new
rescue ex : ErrorModule
end

This gives more flexibility for exception hierarchies allowing multiple ancestors instead of only a single super class. For example, you can have a common module for all exceptions of a specific part of a library, while they can still inherit from different external exception types. More details in #14552

Thanks @Blacksmoke16

Macros

  • New methods in the macro language for AST nodes for macro-related nodes (#14492) and Select (#14600)

    Thanks @HertzDevil

  • New methods expose a type node’s visibility: TypeNode#private?, #public? and #visibility (#11696)

    Thanks @Hadeweka

  • New macro method StringLiteral#to_utf16 (#14676)

    Thanks @ysbaddaden

Runtime Tracing

The Crystal runtime has a new tracing feature for low level functionality. It currently covers garbage collector and scheduler activity (#14659). A program built with -Dtracing prints diagnostic info when enabled via environment variable CRYSTAL_TRACE=all (or CRYSTAL_TRACE=gc, CRYSTAL_TRACE=sched). Output goes to STDERR by default, but can be configured via CRYSTAL_TRACE_FILE=tracing.log.

$ crystal build -Dtracing hello-world.cr
$ CRYSTAL_TRACE=sched ./hello-world
sched.spawn 70569399740240 thread=0x7f48d7dc9740:? fiber=0x7f48d7cd0f00:main fiber=0x7f48d7cd0dc0:Signal Loop
sched.enqueue 70569399831716 thread=0x7f48d7dc9740:? fiber=0x7f48d7cd0f00:main fiber=0x7f48d7cd0dc0:Signal Loop duration=163
Hello World

Thanks @ysbaddaden and 84codes

WaitGroup

A WaitGroup is a declarative counter of concurrent fibers. Each such fiber is expected to call #done when it has finished. Whenever the counter reaches zero the waiters are resumed. This is a simpler and more efficient alternative to Channel(Nil). Read more in #14167.

require "wait_group"

wg = WaitGroup.new

5.times do
  wg.add
  spawn do
    puts "waiting..."
    sleep rand.seconds
  ensure
    wg.done
  end
end

# suspend the current fiber until the 5 fibers are done
wg.wait

Thanks @ysbaddaden and 84codes

Compiler

Misc

Deprecations

  • File.readable?, .writable?, .executable? are moved to File::Info. They are low-level methods and removing them from the prominent File namespace reduces potential for confusion. (#14484)

    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