Hi Guys,
one more time I had this need for a simple while loop and so I played with this macro idea: https://hex.pm/packages/while
While on globals
import While
ref = :counters.new(1, [:atomics])
while :counters.get(ref 1) < 10 do
:counters.add(ref 1, 1)
end
IO.puts("Current value is #{:counters.get(ref, 1)}")
Now this only works when you’re working with globals, references or pids, which in fact in my case is useful sometimes. But to make it more useful in local scopes I created a more reduce like shortcut:
While on locals
When providing an additional parameter, this is interpreted as a variable name and imported into the scope of the while expression and the while body.
import While
cnt = 1
cnt = while cnt, cnt < 10 do
cnt + 1
end
IO.puts("Current value is #{cnt}")
Explanation:
The while/3
binds the variable name cnt
to both the expression cnt < 10
and to the body. The body result (last line of body) always becomes the new value for the bound variable, like in a Enum.reduce
.
cnt - 1
Danger Area
To automate the assignment, there is another variant while_with
that will automagically assign to the original variable. Consensus from this discussion seems to be: Don’t use this variant
import While
cnt = 1
while_with cnt, cnt < 10 do
cnt + 1
end
IO.puts("Current value is #{cnt}")
Explanation:
The while_with
works exactly like while/3
but the final value, will be assigned to the bound variable of the outer scope, so that: IO.puts("Current value is #{cnt}")
will print Current value is 10
Questions
The name while_with might be confusing, should this just be the same name, but a two parameter variant of while , or should it be called reduce_while or something? Curious about the communities thoughts here and whether this kind of macro has any reason to exist at all in the first place
Installation
While can be installed by adding while to your list of dependencies in mix.exs:
def deps do
[
{:while, "~> 0.2.1"}
]
end