---
title: Crystal 1.4.0 is released!
version: 1.4.0
summary:
thumbnail: +
author:
comment_href: https://disqus.com/home/discussion/crystal-lang/crystal_140_is_released/
---

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](https://github.com/crystal-lang/crystal/releases/tag/1.4.0). Those excited by the new [interpreter](https://crystal-lang.org/2021/12/29/crystal-i.html) might be happy to find the ongoing efforts to improve it. 

Pre-built packages are available on [GitHub Releases](https://github.com/crystal-lang/crystal/releases/tag/1.4.0) and our official distribution channels.
See [crystal-lang.org/install](https://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](https://github.com/crystal-lang/crystal/pulls?q=is%3Apr+milestone%3A1.4.0) 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](https://github.com/crystal-lang/crystal/pull/10870) for details. The updated instructions to try it out are:

1. Write a simple Crystal program, let's say: 
```crystal
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.

2. You need to have `wasm-ld` installed on your system, it is the WebAssembly linker from LLVM.
On some systems, it comes by installing `lld`. Confirm that it is installed by using
`wasm-ld --version`. Please also check that its version is similar to Crystal's LLVM version
(`crystal --version`).

3. You will need `libc` and `libpcre` compiled to the `wasm32-wasi` target. You can fetch a
precompiled version of them [here](https://github.com/lbguilherme/wasm-libs/releases).
Check for the `wasm32-wasi-libs.tar.gz` asset, download it and extract it.

4. Cross-compile it with `crystal build main.cr --cross-compile --target wasm32-wasi`.

5. Link it with
```bash
wasm-ld main.wasm -o main-final.wasm  -L "$PWD/wasm32-wasi-libs" -lc -lpcre -lclang_rt.builtins-wasm32
```

6. Run the WebAssembly module with `wasmer main-final.wasm` or `wasmtime main-final.wasm` and have fun.

Note: There is currently [#11948](https://github.com/crystal-lang/crystal/pull/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:

```crystal
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](https://github.com/crystal-lang/crystal/pull/11812)):

```crystal
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:

```crystal
[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:
    
```crystal
h = {"a" => 0, "b" => 1}
h.update("b") { |v| v + 41 } # => 1
h["b"]                       # => 42
```

Details in the [docs](https://crystal-lang.org/api/1.4.0/Hash.html#update%28key%3AK%2C%26%3AV-%3EV%29%3AV-instance-method).

## Other remarkable changes

- Support for LLVM 14 ([#11905](https://github.com/crystal-lang/crystal/pull/11905)).
- Completed compiler support for `Int128` ([#11576](https://github.com/crystal-lang/crystal/pull/11576)).
- ⚠️ Support for scientific notation in `BigFloat#to_s` ([#10632](https://github.com/crystal-lang/crystal/pull/10632)).
- ⚠️ Drop support of undocumented flag `skip_abstract_def_check` ([#9217](https://github.com/crystal-lang/crystal/pull/9217)).
- New `IO#getb_to_end` method for reading all the `Bytes` of an `IO` ([docs](https://crystal-lang.org/api/1.4.0/IO.html#getb_to_end%3ABytes-instance-method)).
- New macro method `parse_type` to parse a type given as a `String` ([docs](https://crystal-lang.org/api/1.4.0/Crystal/Macros.html#parse_type%28type_name%3AStringLiteral%29%3APath%7CGeneric%7CProcNotation%7CMetaclass-instance-method)).

> **THANKS:**
> We have been able to do all of this thanks to the continued support of [84codes](https://www.84codes.com/), [Nikola Motor Company](https://nikolamotor.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 [crystal@manas.tech](mailto:crystal@manas.tech) if you’d like to become a direct sponsor or find other ways to support Crystal. We thank you in advance!
