Remove element from list and store it in variable?
Maybe something like:
push[stackID_][e_] := Last[$Stack[stackID] = {$Stack[stackID], e}]
pop[stackID_] := Replace[$Stack[stackID],
{
{s_, e_} :> ($Stack[stackID] = s; e),
_ -> Missing["Empty"]
}
]
stack[stackID_] := $Stack[stackID]
empty[stackID_] := Quiet[Unset@$Stack[stackID];, Unset::norep]
$Stack[_]={};
For example, push 1 through 5 to stack id 1:
push[1] /@ Range[5]
{1, 2, 3, 4, 5}
Then, pop 6 elements from stack id 1:
Table[pop[1], {6}]
{5, 4, 3, 2, 1, Missing["Empty"]}
Note that the stack is implemented as a nested list instead of a flat list for efficiency reasons. So:
empty[1]
push[1] /@ Range[3];
stack[1]
{{{{}, 1}, 2}, 3}
Changing the implementation to a flat list is simple, although you will take a performance hit for long stacks ($O(n)$ vs $O(1)$).
Here is one possible implementation that is somewhat Mathematica-idiomatic. Using your list:
stack = {one, two, three};
ClearAll@fetchFromStack
Attributes[fetchFromStack] = HoldAll
fetchFromStack[stack_Symbol /; Evaluate[stack] === {}] := (stack = {};False)
fetchFromStack[stack_Symbol : {elem_}] := (stack = {}; elem)
fetchFromStack[stack_Symbol] := Module[{x = stack[[1]]},
stack = stack[[2 ;;]];
x
]
Then:
stack = {one, two, three};
Table[{fetchFromStack[stack], stack}, {5}]
(* {{one, {two, three}}, {two, {three}}, {three, {}}, {False, {}}, {False, {}}} *)
One more:
ClearAll[fetch];
SetAttributes[fetch, HoldFirst];
fetch[stack_Symbol] := If[Length[stack] > 0,
Module[{h}, {{h}, stack} = TakeDrop[stack, 1]; h],
False
]
Now
stack = {one, two, three};
fetch[stack]
fetch[stack]
fetch[stack]
fetch[stack]
(* one *)
(* two *)
(* three *)
(* False *)