Skip to content

Commit 5668ab2

Browse files
committed
Update CHANGELOG
1 parent dad1b86 commit 5668ab2

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

CHANGELOG.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,89 @@
11
# Changelog for Elixir v1.12
22

3+
Elixir v1.12 is out with improvements to scripting, tighter Erlang/OTP 24 integration, stepped ranges, and dozen of new functions across the standard library. Overall this is a small release, which continues our tradition of bringing Elixir developers quality of live improvements every 6 months.
4+
5+
## Scripting improvements: `Mix.install/2` and `System.trap_signal/3`
6+
7+
Elixir v1.12 brings new conveniences for those using Elixir for scripting (via `.exs` files). Elixir has been capable of managing dependencies for a quite long time, but it could only be done within Mix projects. In particular, the Elixir team is wary of global dependencies as any scripts that rely on system packages are brittle and hard to reproduce whenever your system changes.
8+
9+
`Mix.install/2` is meant to be a sweetspot between single-file scripts and full-blown Mix projects. With `Mix.install/2`, you can list your dependencies on top of your scripts. When you execute the script for the first time, Elixir will download, compile, and cache your dependencies before running your script. Future invocations of the script will simply read the compiled artefacts from the cache:
10+
11+
```elixir
12+
Mix.install([:jason])
13+
IO.puts Jason.encode!(%{hello: :world})
14+
```
15+
16+
`Mix.install/2` also performs protocol consolidation, which gives script developers an option to execute their code in the most performant format possible.
17+
18+
Another improvement to scripting is the ability to trap exit signals via `System.trap_signal/3`. All you need is the signal name and a callback that will be invoked when the signal triggers. For example, ExUnit leverages this functionality to print all currently running tests when you abort the test suite via SIGQUIT (`Ctrl+\\ `):
19+
20+
```
21+
$ mix test
22+
............................................
23+
...........^\
24+
25+
Aborting test suite, the following have not completed:
26+
27+
* test query building [test/ecto/query_test.exs:48]
28+
* test placeholders in Repo.insert_all [test/ecto/repo_test.exs:502]
29+
30+
Showing results so far...
31+
32+
78 doctests, 1042 tests, 0 failures
33+
```
34+
35+
This is particularly useful when your tests get stuck and you want to know which one is the culprit.
36+
37+
**Important**: Trapping signals may have strong implications on how a system shuts down and behave in production and therefore it is extremely discouraged for libraries to set their own traps. Instead, they should redirect users to configure them themselves. The only cases where it is acceptable for libraries to set their own traps is when using Elixir in script mode, such as in `.exs` files and via Mix tasks.
38+
39+
## Tighter Erlang/OTP 24 integration
40+
41+
Erlang/OTP 24 ships with JIT compilation support and Elixir developers don't have to do anything to reap its benefits. There are many other features in Erlang/OTP 24 to look forwards to and Elixir v1.12 provides integration with many of them: such as support for 16bit floats in bitstrings as well as performance improvements in the compiler and during code evaluation.
42+
43+
Another excellent feature in Erlang/OTP 24 is the implementation of [EEP 54](http://erlang.org/eeps/eep-0054.html), which provides extended error information for many functions in Erlang's stdlib. Elixir v1.12 fully leverages this feature to improve reporting for errors coming from Erlang. For example, in earlier OTP versions, inserting an invalid argument into a ETS table that no longer exists would simply error with `ArgumentError`:
44+
45+
```
46+
Interactive Elixir (1.11.0)
47+
iex(1)> ets = :ets.new(:example, [])
48+
#Reference<0.3845811859.2669281281.223553>
49+
iex(2)> :ets.delete(ets)
50+
true
51+
iex(3)> :ets.insert(ets, :should_be_a_tuple)
52+
** (ArgumentError) argument error
53+
(stdlib 3.15) :ets.insert(#Reference<0.3845811859.2669281281.223553>, :should_be_a_tuple)
54+
```
55+
56+
However, in Elixir v1.12 with Erlang/OTP 24:
57+
58+
```
59+
Interactive Elixir (1.12.0)
60+
iex(1)> ets = :ets.new(:example, [])
61+
#Reference<0.105641012.1058144260.76455>
62+
iex(2)> :ets.delete(ets)
63+
true
64+
iex(3)> :ets.insert(ets, :should_be_a_tuple)
65+
** (ArgumentError) errors were found at the given arguments:
66+
67+
* 1st argument: the table identifier does not refer to an existing ETS table
68+
* 2nd argument: not a tuple
69+
70+
(stdlib 3.15) :ets.insert(#Reference<0.105641012.1058144260.76455>, :should_be_a_tuple)
71+
```
72+
73+
## Stepped ranges
74+
75+
Elixir has support for ranges from before its v1.0 release. Ranges support only integers and are inclusive, using the mathematic notation `a..b`. Ranges in Elixir are either increasing `1..10` or decreasing `10..1` and the direction of the range was always inferred from the starting and stop positions.
76+
77+
Unfortunately, due to this inference, it is not possible to have empty ranges. For example, if you want to create a list of `n` elements, you can express it with a range from `1..n`, as `1..0` is a decreasing range with two elements.
78+
79+
Elixir v1.12 supports stepped ranges via the `first..last//step` notation. For example: `1..10/2` will emit the numbers `1`, `3`, `5`, `7`, and `9`. You can consider the `//` operator to be a "range modulo" operation, as it effectively divides the number of elements in the range by `step`. Steps can be either positive (increasing ranges) or negative (decreasing ranges). Stepped ranges bring more expressive power to Elixir ranges and they elegantly solve the empty range problem, as they allow the direction of the steps to be explicitly declared instead of inferred.
80+
81+
As of Elixir v1.12, implicitly decreasing ranges are soft-deprecated and warnings will be emitted in future Elixir versions based on our [deprecation policy](https://hexdocs.pm/elixir/compatibility-and-deprecations.html#deprecations).
82+
83+
## Additional functions
84+
85+
Elixir v1.12 has the additional of many functions across the standard library. The `Enum` module received additions such as `Enum.count_until/2`, `Enum.product/1`, `Enum.zip_with/2`, and more. The `Integer` module now includes `Integer.pow/2` and `Integer.extended_gcd/2`. The `Range` module now deals with stepped ranges and includes new convenience functions such as `Range.empty?/1` and `Range.size/1`. Finally, the `Kernel` module got two new functions, `Kernel.then/2` and `Kernel.tap/2`, which are specially useful in `|>` pipelines.
86+
387
## v1.12.0-dev
488

589
### 1. Enhancements
@@ -14,11 +98,13 @@
1498
* [Code] Do not add newlines around interpolation on code formatting. Note this means formatted code that has interpolation after the line length on Elixir v1.12 won't be considered as formatted on earlier Elixir versions
1599
* [Calendar] Support basic datetime format in `Calendar.ISO` parsing functions
16100
* [Code] Improve evaluation performance on systems running on Erlang/OTP 24+
101+
* [Date] Support steps via `Date.range/3`
17102
* [DateTime] Add `offset` to `DateTime.to_iso8601/2` (now `to_iso8601/3`)
18103
* [Enum] Add `Enum.count_until/2` and `Enum.count_until/3`
19104
* [Enum] Add `Enum.product/1`
20105
* [Enum] Add `Enum.zip_with/2` and `Enum.zip_with/3`
21106
* [Enum] Add support for functions as the second argument of `Enum.with_index/2`
107+
* [Exception] Show `error_info` data for exceptions coming from Erlang
22108
* [Float] Add `Float.pow/2`
23109
* [Integer] Add `Integer.pow/2` and `Integer.extended_gcd/2`
24110
* [List] Add default value for `List.first/1` and `List.last/1`

0 commit comments

Comments
 (0)