summaryrefslogtreecommitdiff
path: root/CHANGELOG.md
blob: 7bdef3710cc09f5e301fbea3e3eb3e129478f932 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# Changelog for Elixir v1.5

Elixir v1.5 brings new features, enhancements and bug fixes to Elixir. It is the first release to leverage features added as part of Erlang/OTP 20. It is also the last release that supports Erlang/OTP 18.

## UTF-8 atoms, function names and variables

Elixir v1.5 supports non-quoted atoms and variables to be in UTF-8 when using Erlang/OTP 20+. For example:

    test "こんにちは世界" do
      assert :こんにちは世界
    end

Or:

    saudação = "Bom dia!"

Elixir follows the recommendations in [Unicode Annex #31](http://unicode.org/reports/tr31/) to make the language more accessible to other languages and communities. Identifiers must start with a letter or underscore, optionally followed by letters, digits, and underscores. Here letter means any UTF-8 letter-character (optionally with a combining mark) and digit means a UTF-8 decimal-digit-character. If you're using ASCII, this does what you'd expect.

Examples of valid variables are:

    name    josé   _age   まつもと  _42  адрес
    
Examples of invalid variables include:

    name•   a±2  42

Symbols, such as mathematical notations and emoji, are not allowed identifiers.

For a complete reference on Elixir syntax, see the [Syntax Reference](https://hexdocs.pm/elixir/syntax-reference.html). For technical details on Unicode support, see [Unicode Syntax](https://hexdocs.pm/elixir/unicode-syntax.html).

## IEx improvements

IEx got many improvements. The autocompletion system is now capable of autocompleting variables and user imports. New helpers have also been added:

  * `exports/1` lists all exports (functions and macros) in a given module
  * `open/1` opens up the source of a module or function directly in your editor. For example, `open MyApp.Module`
  * `runtime_info/0` prints general information about the running system, such as number of cores, runtime version, allocation of memory in the VM and more

IEx also features a breakpoint system for code debugging. The following functions have been added to aid debugging:

  * `break!/2` - sets up a breakpoint for a given `Mod.fun/arity`
  * `break!/4` - sets up a breakpoint for the given module, function, arity
  * `breaks/0` - prints all breakpoints and their ids
  * `continue/0` - continues until the next breakpoint in the same process
  * `open/0` - opens editor on the current breakpoint
  * `remove_breaks/0` - removes all breakpoints in all modules
  * `remove_breaks/1` - removes all breakpoints in a given module
  * `reset_break/1` - sets the number of stops on the given id to zero
  * `reset_break/3` - sets the number of stops on the given module, function, arity to zer
  * `respawn/0` - starts a new shell (breakpoints will ask for permission once more)
  * `whereami/1` - shows the current location

## Exception.blame

`Exception.blame/3` is a new function in Elixir that is capable of attaching debug information to certain exceptions. Currently this is used to augment `FunctionClauseError`s with a summary of all clauses and which parts of clause match and which ones didn't. For example:

    iex> Access.fetch(:foo, :bar)
    ** (FunctionClauseError) no function clause matching in Access.fetch/2

    The following arguments were given to Access.fetch/2:

        # 1
        :foo

        # 2
        :bar

    Attempted function clauses (showing 5 out of 5):

        def fetch(-%struct{} = container-, key)
        def fetch(map, key) when -is_map(map)-
        def fetch(list, key) when -is_list(list)- and is_atom(key)
        def fetch(list, key) when -is_list(list)-
        def fetch(-nil-, _key)

    (elixir) lib/access.ex:261: Access.fetch/2

In the example above, an argument that did not match or guard that did not evaluate to true are shown between `-`. If the terminal supports ANSI coloring, they are wrapped in red instead of the `-` character.

Since blaming an exception can be expensive, `Exception.blame/3` must be used exclusively in debugging situations. It is not advised to apply it to production components such as a Logger. This feature has been integrated into the compiler, the command line, ExUnit and IEx.

This feature also requires Erlang/OTP 20+.

## Streamlined child specs

Elixir v1.5 streamlines how supervisors are defined and used in Elixir. Elixir now allows child specifications, which specify how a child process is supervised, to be defined in modules. In previous versions, a project using Phoenix would write:

    import Supervisor.Spec

    children = [
      supervisor(MyApp.Repo, []),
      supervisor(MyApp.Endpoint, [])
    ]

    Supervisor.start_link(children, strategy: :one_for_one)

In Elixir v1.5, one might do:

    children = [
      MyApp.Repo,
      MyApp.Endpoint
    ]

    Supervisor.start_link(children, strategy: :one_for_one)

The above works by calling the `child_spec/1` function on the given modules.

This new approach allows `MyApp.Repo` and `MyApp.Endpoint` to control how they run under a supervisor. This reduces the chances of mistakes being made, such as starting an Ecto repository as a worker or forgetting to declare that tasks are temporary in a supervision tree.

If it is necessary to configure any of the children, such can be done by passing a tuple instead of an atom:

    children = [
      {MyApp.Repo, url: "ecto://localhost:4567/my_dev"},
      MyApp.Endpoint
    ]

The modules `Agent`, `Registry`, `Task`, and `Task.Supervisor` have been updated to include a `child_spec/1` function, allowing them to be used directly in a supervision tree similar to the examples above. `use Agent`, `use GenServer`, `use Supervisor`, and `use Task` have also been updated to automatically define an overridable `child_spec/1` function.

Finally, child specifications are now provided as maps (data-structures) instead of the previous `Supervisor.Spec.worker/3` and `Supervisor.Spec.supervisor/3` APIs. This behaviour also aligns with how supervisors are configured in Erlang/OTP 18+. See the updated `Supervisor` docs for more information, as well as the new `Supervisor.init/2` and `Supervisor.child_spec/2` functions.

## @impl

This release also allows developers to mark which functions in a given module are an implementation of a callback. For example, when using the [Plug](https://github.com/elixir-lang/plug) project, one needs to implement both `init/1` and `call/2` when writing a Plug:

    defmodule MyApp do
      @behaviour Plug

      def init(_opts) do
        opts
      end

      def call(conn, _opts) do
        Plug.Conn.send_resp(conn, 200, "hello world")
      end
    end

The problem with the approach above is that, once more and more functions are added to the `MyApp` module, it becomes increasingly harder to know the purposes of the `init/1` and `call/2` functions. For example, for a developer unfamiliar with Plug, are those functions part of the `MyApp` API or are they implementations of a given callback?

Elixir v1.5 introduces the `@impl` attribute, which allows us to mark that certain functions are implementation of callbacks:

    defmodule MyApp do
      @behaviour Plug

      @impl true
      def init(_opts) do
        opts
      end

      @impl true
      def call(conn, _opts) do
        Plug.Conn.send_resp(conn, 200, "hello world")
      end
    end

You may even use `@impl Plug` if you want to explicitly document which behaviour defines the callback you are implementing.

Overall, using `@impl` has the following advantages:

  * Readability of the code is increased, as it is now clear which functions are part of your API and which ones are callback implementations. To reinforce this idea, `@impl true` automatically marks the function as `@doc false`, disabling documentation unless `@doc` is explicitly set

  * If you define `@impl` before a function that is not a callback, Elixir will error. This is useful in case of typos or in case the behaviour definition changes (such as a new major version of a library you depend on is released)

  * If you use `@impl` in one implementation, Elixir will force you to declare `@impl` for all other implementations in the same module, keeping your modules consistent

## Calendar improvements

This release brings further improvements to Calendar types. It adds arithmetic and others functions to `Time`, `Date`, `NaiveDateTime` and `Datetime` as well as conversion between different calendars.

## v1.5.3 (2017-12-15)

### 1. Bug fixes

#### Elixir

  * [Calendar] Consider microseconds in maximum possible Calendar.ISO datetime
  * [Enum] Fix `chunk_every/4` when `step > count`
  * [Kernel] Warn duplicate definitions in macros
  * [Kernel] Remove dialyzer warnings from else in with clauses
  * [Kernel] Do not warning on upcoming `@deprecated` and `@since` attributes for v1.6
  * [MapSet] Return valid MapSet when union-ing a legacy MapSet

#### ExUnit

  * [ExUnit] Fix compiler warnings in `assert_receive/3`

## v1.5.2 (2017-09-29)

### 1. Enhacements

#### Elixir

  * [Kernel] Optimize function definition with multiple clauses by not traversing the internal clauses table
  * [Kernel] Warn if unary operators are followed by new lines
  * [Registry] Use the name of the Registry as its `:id` in the `child_spec/1` function

### 2. Bug fixes

#### Elixir

  * [DateTime] Fix negative microsecond result when passing negative Unix epochs to `from_unix/2`
  * [Kernel] Improve error message for oversized atoms
  * [Kernel] Ensure `@impl` attribute also propagates to clauses from default arguments
  * [Kernel] Emit proper error for unknown vars inside binary pattern in match

#### IEx

  * [IEx] Do not crash IEx unexpectedly on `System.stop/0`
  * [IEx.Helpers] Ensure exiting a breakpoint set inside a breakpoint does not terminate the shell unexpectedly

#### Mix

  * [mix local.hex] Ensure `--if-missing` flag works as advertised
  * [mix test] Do not trigger additional error reports when there is a failure when loading test files
  * [Mix.SCM.Git] Ensure errors when invoking `git` propagate correctly

## v1.5.1 (2017-08-01)

### 1. Enhancements

#### EEx

  * [EEx.Engine] Add `handle_begin` and `handle_end` to EEx

#### Elixir

  * [Kernel] Do not use references on function/macro definitions - this provides large improvements in compilation times in some rare corner cases
  * [Supervisor] Support mixing old and new typespecs in `Supervisor.init/2` and `Supevisor.start_link/2`

#### Mix

  * [mix profile] Allow profile tasks to run without a project

### 2. Bug fixes

#### EEx

  * [EEx.Engine] Do not re-use the value of the `init/1` callback throughout the compilation stack

#### Elixir

  * [Kernel] Ensure dialyzer does not emit warnings in some uses of `with`
  * [Kernel] Fix dialyzer warnings when `defmacrop` is used in modules
  * [Kernel] Ensure Elixir modules can be dialyzed without starting the Elixir application
  * [Kernel] Do not serialize references in quoted expressions
  * [Kernel] Make sure structs expansion use the latest definition available when struct modules are recompiled
  * [Task] Support `:infinity` timeout on Task streams
  * [Typespec] Ensure typespecs allow `tuple` to be used as variable names

## v1.5.0 (2017-07-25)

### 1. Enhancements

#### Elixir

  * [Access] Optimize `Access.get/2`
  * [Base] Optimise Base encode/decode
  * [Calendar] Implement Inspect for DateTime with Calendar.ISO
  * [Calendar] Add "ISO days" format for conversions between Calendars and `Date.convert/2`, `Time.convert/2`, `NaiveDateTime.convert/2` and `DateTime.convert/2` (as well as bang variants)
  * [Calendar] Add `:calendar` field to `Time` struct
  * [Calendar] Add `Time.diff/3`, `Date.add/2`, `Date.diff/2`, `DateTime.diff/3`
  * [Calendar] Add `Date.range/2`
  * [Calendar] Add `Date.new/4`, `DateTime.utc_now/1`, `NaiveDateTime.new/8` and `Time.new/5` that allow specifing calendar
  * [Enum] Add `Enum.chunk_by/4` and `Stream.chunk_by/4`
  * [Enum] Add `Enum.chunk_every/2` and `Enum.chunk_every/4` with a more explicit API than `Enum.chunk/2` and `Enum.chunk/4`
  * [Exception] Add `Exception.blame/3` that adds metadata to exceptions
  * [File] Add `File.read_link/1` and `File.read_link!/1`
  * [File] Introduce `:trim_bom` option for `File.stream!/2`
  * [Inspect] Add `:printable_limit` to control the limit of printable structures
  * [Integer] Add `Integer.gcd/2`
  * [Kernel] Add `left not in right` to check that the left side is not in the enumerable on the right
  * [Kernel] Use the new `debug_info` chunk in OTP 20. This provides a mechanism for tools to retrieve the Elixir AST from beam files
  * [Kernel] `defoverridable/1` accepts a module name as argument and marks all callbacks as overridable
  * [Kernel] Allow non-quoted Unicode atoms and variables according to Unicode Annex #31 (see Unicode Syntax document)
  * [Kernel] Warn when a `:__struct__` key is used when building/updating structs
  * [Kernel] Cache the AST on definitions. This speeds up the compilation time from 10% to 15% measured across different projects
  * [Kernel] Improve compiler error message on invalid patterns and guards
  * [Keyword] Add `replace/3` and `replace!/3` for replacing an existing key
  * [List] `List.starts_with?/2`
  * [Macro] Introduce `Macro.generate_arguments/2`
  * [Map] Optimize `Map.merge/3` by choosing merging direction
  * [Map] Add `replace/3` and `replace!/3` for replacing an existing key
  * [Map] Raise `BadMapError` in `Map.equal?/2` when either of the two arguments is not a map
  * [MapSet] Reduce `MapSet` size when serialized to approximately half
  * [Process] Add `Process.cancel_timer/2`
  * [Protocol] Show available implementations on `Protocol.UndefinedError` if the protocol has been consolidated
  * [Registry] Support ETS guard conditions in `Registry.match/3`
  * [Registry] Support `parallel: true` in `Registry.dispatch/3`
  * [Registry] Introduce `Registry.unregister_match/4`
  * [Stream] Add `Stream.chunk_every/2` and `Stream.chunk_every/4` with a more explicit API than `Stream.chunk/2` and `Stream.chunk/4`
  * [String] Optimise binary pattern matching in `String.split/1` and `String.trim_*/1`
  * [Supervisor] Add `Supervisor.init/2` and `Supervisor.child_spec/2`
  * [Supervisor] Allow `module` and `{module, arg}` to be given to `Supervisor.start_link/2` and invoke `module.child_spec(arg)` on each argument
  * [Task] Support `:on_timeout` in `Task.async_stream` to control how tasks are terminated
  * [Task] Add `ordered: false` support to `Task.async_stream`

#### ExUnit

  * [ExUnit] Show code snippet from test source file in case of test errors
  * [ExUnit] Use `Exception.blame/3` when formatting test errors
  * [ExUnit] Make `assert_raise/2` fail if the underlying exception has a broken `message/1` implementation
  * [ExUnit] Add `start_supervised/2` and `stop_supervised/1` to ExUnit. Processes started by this function are automatically shut down when the test exits

#### IEx

  * [IEx.Autocomplete] Support autocompletion of variable names
  * [IEx.Autocomplete] Support autocompletion of functions imported using `import Mod, only: [...]`
  * [IEx.Evaluator] Use `Exception.blame/3` when showing errors in the terminal
  * [IEx.Helpers] Add `exports/1` IEx helper to list all exports in a module
  * [IEx.Helpers] Add `break!/2`, `break!/4`, `breaks/0`, `continue/0`, `open/0`, `remove_breaks/0`, `remove_breaks/1`, `reset_break/1`, `reset_break/3` and `whereami/1` for code debugging
  * [IEx.Helpers] No longer emit warnings for IEx commands without parentheses
  * [IEx.Helpers] Add `runtime_info/0` for printing runtime system information
  * [IEx.Helpers] Add `open/1` to open the source of a given module/function in your editor
  * [IEx.Info] Implement `IEx.Info` protocol for calendar types

#### Logger

  * [Logger] Add `metadata: :all` configuration to log all metadata

#### Mix

  * [mix compile.elixir] Add `--all-warnings` option to Elixir compiler that shows all warnings from the previous compilation (instead of just of the files being compiled)
  * [mix escript.build] Strip debug information from escripts by default and add option `:strip_beam` which defaults to true
  * [mix loadpaths] Ensure `--no-deps-check` do not trigger SCM callbacks (such as `git`)
  * [mix local.hex] Add `--if-missing` flag to `local.hex` mix task
  * [mix profile.cprof] Add `Mix.Tasks.Profile.Cprof` for count-based profiling
  * [mix new] New styling for generated applications

### 2. Bug fixes

#### Elixir

  * [Calendar] Ensure `Calendar.ISO` raises a readable error when reaching up the year 10000 restriction
  * [Calendar] Return `{:error, :invalid_time}` for wrong precision instead of crashing when parsing ISO dates
  * [Enumerable] Raise `Protocol.UndefinedError` on bad functions in Enumerable implementation
  * [File] Ensure recursive file operations raise on paths with null bytes (*security issue reported by Griffin Byatt*)
  * [File] Support `:ram`/`:raw` files in `File.copy/2`
  * [Inspect] Do not use colors when inspecting error messages
  * [Kernel] Support guards on anonymous functions of zero arity
  * [Kernel] Fix compilation of maps used as maps keys inside matches
  * [Kernel] Ensure `do` clause in `with` is tail call optimizable
  * [Module] `on_definition/6` callback receives body wrapped in a keyword list, such as `[do: body]`. This solves a bug where it was impossible to distinguish between a bodyless clause and a function that returns `nil`.
  * [Path] Ensure recursive path operations raise on paths with null bytes (*security issue reported by Griffin Byatt*)
  * [Protocol] Do not lose source compile info on protocol consolidation
  * [Record] Properly escape quoted expressions passed to `defrecord`
  * [Regex] Fix `inspect/2` for regexes with `/` terminator in them
  * [Registry] Ensure `Registry.match/4` works with `:_` as key
  * [Stream] Fix stream cycle over empty enumerable
  * [String] Consider Unicode non-characters valid according to the specification in `String.valid?/1`
  * [StringIO] Fix encoding and performance issues in `StringIO.get_until`
  * [System] Raise on paths with null bytes in `System.cmd/2` and in `System.find_executable/1` (*security issue reported by Griffin Byatt*)
  * [System] Raise on ill-formed environment variables (*security issue reported by Griffin Byatt*)

#### ExUnit

  * [ExUnit] Properly account failed tests when `setup_all` fails
  * [ExUnit] Having two or more `describe` blocks with the same name will now raise an error.

#### IEx

  * [IEx] Skip autocompletion of module names that are invalid without being quoted
  * [IEx] Skip autocompletion of functions with default arguments with `@doc false`
  * [IEx] Do not start oldshell alongside IEx

#### Mix

  * [mix compile.elixir] Store multiple sources in case of module conflicts. This solves an issue where `_build` would get corrupted when compiling Elixir projects with module conflicts
  * [mix compile.erlang] Do not silently discard Erlang compile errors
  * [mix compile.erlang] Properly track `-compile` module attribute when specified as a list
  * [mix compile.protocols] Ensure protocol implementations do not "disappear" when switching between applications in umbrella projects by having separate consolidation paths per project
  * [mix compile.protocols] Do not raise when consolidating a protocol that was converted into a module

### 3. Soft deprecations (no warnings emitted)

#### Elixir

  * [Kernel] `not left in right` is soft-deprecated in favor of `left not in right`

### 4. Deprecations

#### Elixir

  * `Atom.to_char_list/1`, `Float.to_char_list/1`, `Integer.to_char_list/1`, `Integer.to_char_list/2`, `Kernel.to_char_list/1`, `List.Chars.to_char_list/1`, `String.to_char_list/1` have been deprecated in favor of their `to_charlist` version. This aligns with the naming conventions in both Erlang and Elixir
  * [Enum] Deprecate `Enum.filter_map/3` in favor of `Enum.filter/2` + `Enum.map/2` or for-comprehensions
  * [GenEvent] Deprecate `GenEvent` and provide alternatives in its docs
  * [Kernel] Using `()` to mean `nil` is deprecated
  * [Kernel] `:as_char_lists value` in `Inspect.Opts.t/0` type, in favor of `:as_charlists`
  * [Kernel] `:char_lists` key in `Inspect.Opts.t/0` type, in favor of `:charlists`
  * [Module] Using Erlang parse transforms via `@compile {:parse_transform, _}` is deprecated
  * [Stream] Deprecate `Stream.filter_map/3` in favor of `Stream.filter/2` + `Stream.map/2`
  * [String] `String.ljust/3` and `String.rjust/3` are deprecated in favor of `String.pad_leading/3` and `String.pad_trailing/3` with a binary padding
  * [String] `String.strip/1` and `String.strip/2` are deprecated in favor of `String.trim/1` and `String.trim/2`
  * [String] `String.lstrip/1` and `String.rstrip/1` are deprecated in favor of `String.trim_leading/1` and `String.trim_trailing/1`
  * [String] `String.lstrip/2` and `String.rstrip/2` are deprecated in favor of `String.trim_leading/2` and `String.trim_trailing/2` with a binary as second argument
  * [Typespec] `char_list/0` type is deprecated in favor of `charlist/0`

#### EEx

  * [EEx] Deprecate `<%= ` in "middle" and "end" expressions, e.g.: `<%= else %>` and `<%= end %>`

## v1.4

The CHANGELOG for v1.4 releases can be found [in the v1.4 branch](https://github.com/elixir-lang/elixir/blob/v1.4/CHANGELOG.md).