The actual warning is much more detailed:
$ elixir while.exs
warning: variable "x" is unused
Note variables defined inside case, cond, fn, if and similar do not leak. If you want to conditionally override an existing variable "x", you will have to explicitly return the variable. For example:
if some_condition? do
atom = :one
else
atom = :two
end
should be written as
atom =
if some_condition? do
:one
else
:two
end
Unused variable found at:
while.exs:27
And it turns out it has nothing to do with macros:
defmodule Test do
def go do
x = 7
try do
for _ <- Stream.cycle([:ok]) do
if x > 4 do
IO.puts x
x = x - 1
else
throw :break
end
end
catch
:break -> :ok
end
end
end
has exactly the same problem. for
is a list comprehension (not a “for loop”) - so I suspect that each element (:ok
) of the stream creates a new closure that initializes x
to its current value 7
. What the compiler is warning you about is that the closure’s value of x
isn’t used anywhere.
There was a discussion about a “while” loop a while back.
If you look at the examples in the book (p.25) you should notice that there is nothing in block
that is driving towards the terminating condition for expression
- i.e. there is nothing happening in block
that changes the state expression
is inspecting.