Celebrating the first year of the 1.X series of our beloved language, we are delivering a new release with several bugfixes and improvements.
Below we list the most important or interesting changes, without mentioning the several bugfixes and smaller enhancements. For more details, visit the changelog. Those excited by the new interpreter might be happy to find the ongoing efforts to improve it.
Pre-built packages are available on GitHub Releases and our official distribution channels. See crystal-lang.org/install for installation instructions.
As usual, breaking changes are marked with ⚠️.
Stats
In this release we included 132 changes since the 1.3.2 release by 31 contributors. We thank all the effort put into improving the language! ❤️
Towards WASM support
Version 1.4.0 ships with, at the moment, minimal support for compiling into WebAssembly (linking the program with a WASI-based LibC). There are several important pieces missing; please check #10870 for details. The updated instructions to try it out are:
- Write a simple Crystal program, let’s say:
puts "Hello WebAssembly!"
and name it
main.cr
. You can also try more complicated programs, but keep in mind that this is still experimental and not ready for production. -
You need to have
wasm-ld
installed on your system, it is the WebAssembly linker from LLVM. On some systems, it comes by installinglld
. Confirm that it is installed by usingwasm-ld --version
. Please also check that its version is similar to Crystal’s LLVM version (crystal --version
). -
You will need
libc
andlibpcre
compiled to thewasm32-wasi
target. You can fetch a precompiled version of them here. Check for thewasm32-wasi-libs.tar.gz
asset, download it and extract it. -
Cross-compile it with
crystal build main.cr --cross-compile --target wasm32-wasi
. - Link it with
wasm-ld main.wasm -o main-final.wasm -L "$PWD/wasm32-wasi-libs" -lc -lpcre -lclang_rt.builtins-wasm32
- Run the WebAssembly module with
wasmer main-final.wasm
orwasmtime main-final.wasm
and have fun.
Note: There is currently #11948 that will simplify steps 4 and 5 above.
Better type inference for instance and class variables
Previous to this release, a simple program like the following failed to type because it couldn’t infer the type of the instance variable:
class DisplayHello
DELAY = 10.milliseconds
@timer_countdown = DELAY
end
Now it compiles fine, inferring correctly that @timer_countdown
has type Time::Span
. It is also possible to omit types in other cases too (details):
class DisplayHello
def initialize(delay : Time::Span)
@timer_countdown = delay + 10.seconds
end
end
Collections
Enumerable
There are two relevant improvements in this class. First, there are raising variants of #find
and #index
, called #find!
and #index!
respectively:
[1, 2, 3].find! { |x| x > 1 } # => 2
[1, 2, 3].find! { |x| x > 4 } # raises Enumerable::NotFoundError
[1, 2, 3].index! { |x| x > 1 } # => 1
[1, 2, 3].index! { |x| x > 4 } # raises Enumerable::NotFoundError
Second, Enumerable#tally
and #tally_by
can be given an existing hash to populate.
Hash
Hash
also got two improvements. First, select
, select!
and reject
can now receive any enumerable. Prior to 1.4.0, only Array
and Tuple
were accepted.
Second, there is a new method Hash#update
that, given a key and a block, updates the element with the resulting value of the block. The method returns the old value:
h = {"a" => 0, "b" => 1}
h.update("b") { |v| v + 41 } # => 1
h["b"] # => 42
Details in the docs.
Other remarkable changes
- Support for LLVM 14 (#11905).
- Completed compiler support for
Int128
(#11576). - ⚠️ Support for scientific notation in
BigFloat#to_s
(#10632). - ⚠️ Drop support of undocumented flag
skip_abstract_def_check
(#9217). - New
IO#getb_to_end
method for reading all theBytes
of anIO
(docs). - New macro method
parse_type
to parse a type given as aString
(docs).
We have been able to do all of this thanks to the continued support of 84codes, Nikola Motor Company 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!
Celebrating the first year of the 1.X series of our beloved language, we are delivering a new release with several bugfixes and improvements.
Below we list the most important or interesting changes, without mentioning the several bugfixes and smaller enhancements. For more details, visit the changelog. Those excited by the new interpreter might be happy to find the ongoing efforts to improve it.
Pre-built packages are available on GitHub Releases and our official distribution channels. See crystal-lang.org/install for installation instructions.
As usual, breaking changes are marked with ⚠️.
Stats
In this release we included 132 changes since the 1.3.2 release by 31 contributors. We thank all the effort put into improving the language! ❤️
Towards WASM support
Version 1.4.0 ships with, at the moment, minimal support for compiling into WebAssembly (linking the program with a WASI-based LibC). There are several important pieces missing; please check #10870 for details. The updated instructions to try it out are:
and name it
main.cr
. You can also try more complicated programs, but keep in mind that this is still experimental and not ready for production.You need to have
wasm-ld
installed on your system, it is the WebAssembly linker from LLVM. On some systems, it comes by installinglld
. Confirm that it is installed by usingwasm-ld --version
. Please also check that its version is similar to Crystal’s LLVM version (crystal --version
).You will need
libc
andlibpcre
compiled to thewasm32-wasi
target. You can fetch a precompiled version of them here. Check for thewasm32-wasi-libs.tar.gz
asset, download it and extract it.Cross-compile it with
crystal build main.cr --cross-compile --target wasm32-wasi
.wasmer main-final.wasm
orwasmtime main-final.wasm
and have fun.Note: There is currently #11948 that will simplify steps 4 and 5 above.
Better type inference for instance and class variables
Previous to this release, a simple program like the following failed to type because it couldn’t infer the type of the instance variable:
Now it compiles fine, inferring correctly that
@timer_countdown
has typeTime::Span
. It is also possible to omit types in other cases too (details):Collections
Enumerable
There are two relevant improvements in this class. First, there are raising variants of
#find
and#index
, called#find!
and#index!
respectively:Second,
Enumerable#tally
and#tally_by
can be given an existing hash to populate.Hash
Hash
also got two improvements. First,select
,select!
andreject
can now receive any enumerable. Prior to 1.4.0, onlyArray
andTuple
were accepted.Second, there is a new method
Hash#update
that, given a key and a block, updates the element with the resulting value of the block. The method returns the old value:Details in the docs.
Other remarkable changes
Int128
(#11576).BigFloat#to_s
(#10632).skip_abstract_def_check
(#9217).IO#getb_to_end
method for reading all theBytes
of anIO
(docs).parse_type
to parse a type given as aString
(docs).We have been able to do all of this thanks to the continued support of 84codes, Nikola Motor Company 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!