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 *)