Skip to content

Commit a41950e

Browse files
author
José Valim
committed
Update CHANGELOG
1 parent 956af98 commit a41950e

File tree

3 files changed

+92
-22
lines changed

3 files changed

+92
-22
lines changed

CHANGELOG.md

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,91 @@
11
# Changelog for Elixir v1.4
22

3-
## Standard library improvements
3+
Elixir v1.4 brings new features, enhancements and bug fixes into Elixir. The most notable changes are the addition of the `Registry` module and the `Task.async_stream/3` and `Task.async_stream/5` which aids developers in writing concurrent software. Those two features and a couple other improvements are described in detail below.
44

5-
### Registry
5+
Overall this is the smallest release since Elixir v1.0 was launched. This aligns well with our goals and the community expectations of Elixir being a stable language with incremental improvements.
66

7-
TODO
7+
## Registry
88

9-
### Syntax coloring
9+
The registry is a local, decentralized and scalable key-value process storage:
1010

11-
TODO
11+
* Local because keys and values are only accessible to the current node (opposite to distributed)
12+
* Decentralized because there is no single entity responsible for managing the registry
13+
* Scalable because performance scales linearly with the addition of more cores upon partitioning
1214

13-
How to disable: `IEx.configure [colors: [syntax_colors: []]]`
15+
A registry is chosen upon start to have unique or duplicate keys. Every key-value pair is associated to the process registering the key. Keys are automatically removed once the owner process terminates.
1416

15-
### Calendar
17+
iex> Registry.start_link(:unique, MyRegistry)
18+
iex> {:ok, _} = Registry.register(MyRegistry, "hello", 1)
19+
iex> Registry.lookup(MyRegistry, "hello")
20+
[{self(), 1}]
1621

17-
TODO
22+
With the registry, developers can provide dynamic process names, module-function dispatch or even a local pubsub system. See the `Registry` documentation for more information.
1823

19-
### Task.async_stream
24+
## Syntax coloring
2025

21-
TODO
26+
Elixir v1.4 introduces the ability to syntax color inspected data structures:
2227

23-
## Mix improvements
28+
iex> IO.puts inspect([hello: 1, world: "!"], syntax_colors: [atom: :cyan])
29+
[hello: 1, world: "!"]
2430

25-
### Protocol resolution
31+
Coloring is done with ANSI colors as specified in the `IO.ANSI` module.
2632

27-
TODO
33+
IEx automatically relies on this feature to provide syntax coloring for evaluated shell results. This behaviour can be configured via the `:syntax_colors` coloring option:
2834

29-
### Application inflection
35+
IEx.configure [colors: [syntax_colors: [atom: :cyan, string: :green]]]
3036

31-
TODO
37+
To disable coloring altogether, pass an empty list to `:syntax_colors`.
38+
39+
## Calendar
40+
41+
Elixir v1.3 introduced new calendar types. This release continues evolving the Calendar APIs by adding functions for comparing, adding and calculating the difference between types, retrieve the `day_of_week/1`, check if the current date is a `leap_year?/1` and more.
42+
43+
## Task.async_stream
44+
45+
When there is a need to traverse a collection of items concurrently, Elixir developers often resort to tasks:
46+
47+
collection
48+
|> Enum.map(&Task.async(SomeMod, :function, [&1]))
49+
|> Enum.map(&Task.await/1)
50+
51+
While the snippet above works fine in my occasions, for large collections it may be problem as it will spawn as many tasks as there are items in the collection. In many situations, you may want to set a limit of how many tasks will be running concurrently.
52+
53+
`Task.async_stream/3` and `Task.async_stream/5` allows developers to process collections concurrently while controlling the maximum amount of concurrent tasks:
54+
55+
collection
56+
|> Task.async_stream(SomeMod, :function, [], max_concurrency: System.schedulers_online)
57+
58+
Note `Task.async_stream/3` is lazy, allowing developers to partially consume the stream until a condition is reached. Furthermore, `Task.Supervisor.async_stream/4` and `Task.Supervisor.async_stream/6` can be used to ensure the concurrent tasks are spawned under the given supervisor.
59+
60+
## Application inflection
61+
62+
Mix v1.4 now automatically inflects the list of applications that are used on runtime from your dependencies list.
63+
64+
In previous Mix versions, most of your dependencies had to be added both to your dependencies list and applications list. Here is how a `mix.exs` could look like:
65+
66+
def application do
67+
[applications: [:logger, :plug, :postgrex]]
68+
end
69+
70+
def deps do
71+
[{:plug, "~> 1.2"},
72+
{:postgrex, "~> 1.0"}]
73+
end
74+
75+
This was error prone as many developers would not list their dependencies in their applications list. Mix v1.4 now automatically inflects your applications list as long as you leave the `:applications` key empty. The `mix.exs` above can be rewritten to:
76+
77+
def application do
78+
[extra_applications: [:logger]]
79+
end
80+
81+
def deps do
82+
[{:plug, "~> 1.2"},
83+
{:postgrex, "~> 1.0"}]
84+
end
85+
86+
As shown in the example above, any dependency that comes from Erlang or Elixir that is required at runtime can be added to the `:extra_applications` list. Finally, if there is a dependency you don't want to include in the application runtime list, you can do so by specifying the `runtime: false` option:
87+
88+
{:distillery, "> 0.0.0", runtime: false}
3289

3390
## v1.4.0-dev
3491

@@ -50,6 +107,8 @@ TODO
50107
* [Integer] Add `Integer.mod/2` and `Integer.floor_div/2`
51108
* [Kernel] Recognize merge conflict markers in source and provide a readable error message
52109
* [Kernel] Warn on unused module attributes
110+
* [Kernel] Improve compiler message on unexpected end of line
111+
* [Kernel] Raise `BadBooleanError` when a non-boolean is given on the left-hand side of `and`/`or`
53112
* [List] Add `List.pop_at/3`
54113
* [List] Add `List.myers_difference/2`
55114
* [OptionParser] Expand multi-letter aliases in `OptionParser`
@@ -64,6 +123,7 @@ TODO
64123

65124
#### ExUnit
66125

126+
* [ExUnit.Diff] Use red or green background for whitespace-only diffs
67127
* [ExUnit.Doctest] Allow inspected structures with multiples lines and unicode characters in the doctest result
68128
* [ExUnit.Formatter] Replace lhs/rhs with left/right in the formatter for clarity
69129

@@ -83,6 +143,8 @@ TODO
83143
* [Mix] Check directory existence in `mix new` and ask how to proceed if one exists
84144
* [Mix] Applications built with the `--sup` flag now have an individual module to work as application callback
85145
* [Mix] Add `--formatter` option to `mix test`
146+
* [Mix] Warn if there are non-applications in the `apps` directory for umbrella projects
147+
* [Mix] Automatically inflect the list of applications for Mix projects
86148
* [Mix.Dep] Add warning for invalid paths on `mix deps.clean`
87149
* [Mix.Project] Add `Mix.Project.apps_paths` that returns the paths to children applications in umbrella projects
88150
* [Mix.Rebar] Add `MIX_REBAR` environment variable for overriding local rebar
@@ -93,6 +155,7 @@ TODO
93155

94156
* [Float] Avoid multiple roundings in `Float.{ceil/2, floor/2, round/2}`
95157
* [Kernel] Don't crash in `macro_exported?/3` when dealing with Erlang modules
158+
* [Kernel] Ensure locals calls are rewritten when calling a local function or macro from inside a module
96159
* [Kernel.SpecialForms] Produce meaningful warning when with's else clauses have no effect
97160
* [Macro] Wrap fn calls in parens in `Macro.to_string/2`
98161
* [Macro] Do not print aliases as keys inside keyword lists in `Macro.to_string/2`
@@ -105,6 +168,10 @@ TODO
105168

106169
* [ExUnit] Fix a race condition in `assert_receive` where we would assert a message was not received but show it in the list of messages when the message is delivered right after the timeout value
107170

171+
### IEx
172+
173+
* [IEx.Helpers] Purge consolidated protocols before and after `recompile/0`
174+
108175
### Mix
109176

110177
* [Mix.Dep] Use `gmake` on FreeBSD instead of `make` when compiling make dependencies
@@ -118,6 +185,10 @@ TODO
118185
* [Enum] `Enum.partition/2` has been deprecated in favor of `Enum.split_with/2`
119186
* [System] Deprecate plural time units in favor of singular ones to align with future Erlang releases
120187

188+
#### ExUnit
189+
190+
* [ExUnit] Using GenEvent to implement ExUnit formatters is deprecated. Please use the new `GenServer` based formatters instead
191+
121192
### 4. Deprecations
122193

123194
#### Elixir

lib/ex_unit/lib/ex_unit/case.ex

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,10 @@ defmodule ExUnit.Case do
264264
@doc """
265265
Defines a not implemented test with a string.
266266
267-
Provides a convenient macro that allows a test to be
268-
defined with a string, but not yet implemented. The
269-
resulting test will always fail and print "Not yet
270-
implemented" error message. The resulting test case is
271-
also tagged with :not_implemented.
267+
Provides a convenient macro that allows a test to be defined
268+
with a string, but not yet implemented. The resulting test will
269+
always fail and print "Not implemented" error message. The
270+
resulting test case is also tagged with `:not_implemented`.
272271
273272
## Examples
274273
@@ -278,7 +277,7 @@ defmodule ExUnit.Case do
278277
defmacro test(message) do
279278
quote bind_quoted: binding() do
280279
name = ExUnit.Case.register_test(__ENV__, :test, message, [:not_implemented])
281-
def unquote(name)(_), do: flunk("Not yet implemented")
280+
def unquote(name)(_), do: flunk("Not implemented")
282281
end
283282
end
284283

lib/ex_unit/test/ex_unit_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ defmodule ExUnitTest do
236236
assert ExUnit.run == %{failures: 1, skipped: 0, total: 1}
237237
end)
238238

239-
assert output =~ "Not yet implemented"
239+
assert output =~ "Not implemented"
240240
assert output =~ "1 test, 1 failure"
241241
end
242242

0 commit comments

Comments
 (0)