Skip to content

Commit

Permalink
Update CHANGELOG
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Jan 18, 2025
1 parent c22c907 commit 7e8de3c
Showing 1 changed file with 101 additions and 0 deletions.
101 changes: 101 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,120 @@
# Changelog for Elixir v1.19

## Type system improvements

### More type inference

Elixir now performs inference of whole functions. The best way to show the new capabilities are with examples. Take the following code:

```elixir
def add_foo_and_bar(data) do
data.foo + data.bar
end
```

Elixir now infers that the function expects a `map` as first argument, and the map must have the keys `.foo` and `.bar` which values of either `integer()` or `float()`. The return type will be either `integer()` or `float()`.

Here is another example:

```elixir
def sum_to_string(a, b) do
Integer.to_string(a + b)
end
```

Even though the `+` operator works with both integers and floats, Elixir infers that `a` and `b` must be both integers, as the result of `+` is given to a function that expects an integer. The inferred type information is then used during type checking to find possible typing errors.

### Type checking of protocol dispatch and implementations

This release also adds type checking when dispatching and implementing protocols.

For example, string interpolation in Elixir uses the `String.Chars` protocol. If you pass a value that does not implement said protocol, Elixir will now emit a warning accordingly.

Here is an example passing a range, which cannot be converted into a string, to an interpolation:

```elixir
defmodule Example do
def my_code(first..last//step = range) do
"hello #{range}"
end
end
```

the above emits the following warnings:

```
warning: incompatible value given to string interpolation:
data
it has type:
%Range{first: term(), last: term(), step: term()}
but expected a type that implements the String.Chars protocol, it must be one of:
dynamic(
%Date{} or %DateTime{} or %NaiveDateTime{} or %Time{} or %URI{} or %Version{} or
%Version.Requirement{}
) or atom() or binary() or float() or integer() or list(term())
```

Warnings are also emitted if you pass a data type that does not implement the `Enumerable` protocol as a generator to for-comprehensions:

```elixir
defmodule Example do
def my_code(%Date{} = date) do
for(x <- date, do: x)
end
end
```

will emit:

```
warning: incompatible value given to for-comprehension:
x <- date
it has type:
%Date{year: term(), month: term(), day: term(), calendar: term()}
but expected a type that implements the Enumerable protocol, it must be one of:
dynamic(
%Date.Range{} or %File.Stream{} or %GenEvent.Stream{} or %HashDict{} or %HashSet{} or
%IO.Stream{} or %MapSet{} or %Range{} or %Stream{}
) or fun() or list(term()) or non_struct_map()
```

## v1.19.0-dev

### 1. Enhancements

#### Elixir

* [Code] Add `:migrate_call_parens_on_pipe` formatter option
* [Date] Support durations as the second element in `Date.range/3`
* [Enum] Provide more information on `Enum.OutOfBoundsError`
* [Kernel] Support `min/2` and `max/2` as guards
* [Protocol] Type checking of protocols dispatch and implementations
* [Protocol] Add `Protocol.impl_for/2` and `Protocol.impl_for!/2`

#### IEx

* [IEx.Autocomplete] Functions annotated with `@doc group: "Name"` metadata will appear within their own groups in autocompletion

#### Mix

* [Mix.Tasks.Compile] Add `Mix.Tasks.Compile.reenable/1`

### 2. Bug fixes

#### Mix

* [mix cmd] Preserve argument quoting in subcommands

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

#### Elixir
Expand All @@ -33,6 +133,7 @@
* [Code] The `on_undefined_variable: :warn` is deprecated. Relying on undefined variables becoming function calls will not be supported in the future
* [File] Passing a callback as third argument to `File.cp/3` is deprecated, pass it as a `on_conflict: callback` option instead
* [File] Passing a callback as third argument to `File.cp_r/3` is deprecated, pass it as a `on_conflict: callback` option instead
* [Kernel] The struct update syntax, such as `%URI{uri | path: "/foo/bar"}` is deprecated in favor of pattern matching on the struct when the variable is defined and then using the map update syntax `%{uri | path: "/foo/bar"}`. Thanks to the type system, pattern matching on structs can find more errors, more reliably
* [Kernel.ParallelCompiler] Passing `return_diagnostics: true` as an option is required on `compile`, `compile_to_path` and `require`

#### Logger
Expand Down

0 comments on commit 7e8de3c

Please sign in to comment.