Skip to content

Commit 3790cd8

Browse files
committed
Expand for comprehension false positives
1 parent 2440f3b commit 3790cd8

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

‎lib/elixir/pages/references/gradual-set-theoretic-types.md‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ In the long term, Elixir developers who want static typing guarantees may explic
241241

242242
Elixir's type inference generally avoids emitting false positive type violations: which are warnings emitted by the type checker when there are no runtime errors. However, in some situations, those may happen and are documented below.
243243

244-
#### `for`-comprehensions assume they are executed at least once
244+
#### `for`-comprehensions assume they may be executed zero, once, or multiple times
245245

246246
For comprehensions in Elixir assume they are executed at least once. Take this code:
247247

@@ -257,6 +257,20 @@ end
257257

258258
`x + 1` will fail because it assumes `x` is an atom from the `Atom.to_string(x)` call, even though the function may raise no runtime error if `list` is an empty list. This is intentional, as it helps find discrepancies inside and outside comprehensions. You can address this by explicitly wrapping the comprehension in a `if list != [] do` block (or similar condition).
259259

260+
Similar, when using the `:reduce` option, Elixir assumes the list may be empty and therefore the accumulator must match the result type. Take this contrived example:
261+
262+
```elixir
263+
def example([_ | _] = list) do
264+
Integer.to_string(
265+
for i <- list, reduce: :unused do
266+
_unused -> i * 2
267+
end
268+
)
269+
end
270+
```
271+
272+
Even though the list is non-empty, for-comprehension always assumes the list can be empty, and the code above will fail because passing `:unused` to `Integer.to_string/1` is a typing violation (which will happen if list is empty). You fix this by making sure the accumulator matches the type of the comprehension body.
273+
260274
#### Struct update syntax must be statically proven
261275

262276
Elixir will warn if you use the struct update syntax and it is not statically proven that the given value does not have said struct type. For example:

0 commit comments

Comments
 (0)