Packages

Stack-safe `while do` and `do while` loops in Gleam

Current section

Files

Jump to
gloop src gloop.erl
Raw

src/gloop.erl

-module(gloop).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([while/3, do_while/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" This module called `Gloop` introduces stack-safe, tall-call recursive `while` loops in Gleam.\n"
" The intent is to remove the additional mental burden recursion causes in Gleam.\n"
"\n"
" For an example of how to use this library see gloop_test.gleam in the test folder.\n"
).
-file("src/gloop.gleam", 12).
?DOC(
" This `while` function is stack-safe and checks the condition based on the communicated state\n"
" at the beginning of an iteration.\n"
" If the condition is true then the code handed to the `while` function is run and generates a\n"
" new state in preparation for the next iteration.\n"
" If the condition is false then the code returns the final state and stops.\n"
" As long as the condition is true, the while loop will continue without blowing up the stack.\n"
).
-spec while(HKA, fun((HKA) -> boolean()), fun((HKA) -> HKA)) -> HKA.
while(State, Pre_run_condition, Code_to_run) ->
case Pre_run_condition(State) of
false ->
State;
true ->
New_state = Code_to_run(State),
while(New_state, Pre_run_condition, Code_to_run)
end.
-file("src/gloop.gleam", 29).
?DOC(
" This `do while` function checks the condition using the communicated state at the end\n"
" of an iteration. It therefore runs the code given to the `do while` function AT LEAST once.\n"
" Just as the other while function, it is stack-safe.\n"
).
-spec do_while(HKB, fun((HKB) -> HKB), fun((HKB) -> boolean())) -> HKB.
do_while(State, Code_to_run, Post_run_condition) ->
New_state = Code_to_run(State),
case Post_run_condition(New_state) of
false ->
New_state;
true ->
do_while(New_state, Code_to_run, Post_run_condition)
end.