"you have to shove them all into an array" — Well, painter's algo is just one solution; a z-buffer remembering the depth of previously painted pixels
can truely allow drawing in any order, as you encouter them in the code. And by deciding per-pixel it avoids issues like
occlusion cycles.
Sure that doesn't "eliminate state", I added a whole-frame buffer! But conceptually I think of it as a much smaller departure than "record, sort, replay".
Pedagogically I wouldn't get into either of this until the student (1) understands occlusion and paint order (2) feels that re-ordering code themselves (painter's algo being run in programmer's head not computer) got frustrating...