luser- -droog
unread,Aug 1, 2013, 3:20:35 AM8/1/13You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
I've discovered myself using this little pattern a lot,
but I know it would have been gibberish to me as a beginner.
So this message is to explain how this little loop does
its marvelous job.
count -1 1{-1 roll =}for
To begin with, it's a `for` loop.
init incr fin {-body-} for
So in our loop, init=count (== number of elements on stack),
incr=-1 (counting down), fin=1 (stop at 1). So it's counting
down from the stack size to 1. If we pop something each time
through the loop, then this loop gives a running count of
the stack size.
Now the inside of the loop.
-1 roll =
If you're a real postscript programmer, this line should
bother you. Because `roll` takes 2 arguments: a count of
the number of stack elements it should mess with, and a
number of elements to move from the top (bottom if negative)
to the bottom (top if negative). So `-1 roll` is a curried
application of `roll`, set to always grab 1 element from
the bottom of a yet-to-be-specified total number of elements
and bring it to the top. Then it prints the object with `=`.
So the loop itself, being a `for` loop, pushes the index
on the stack before each iteration of the loop body.
So the stack picture looks something like this:
% a b c d e f g
count % a b c d e f g 7
-1 1 {} % a b c d e f g 7 -1 1 {}
for
**loop push index 7**
% a b c d e f g 7
-1 % a b c d e f g 7 -1
roll % b c d e f g a
= % b c d e f g (output a)
% b c d e f g
**loop push index 6**
% b c d e f g 6
-1 % b c d e f g 6 -1
roll % c d e f g b
= % c d e f g (output b)
% c d e f g
**loop push index 5**
% c d e f g 5
-1 % c d e f g 5 -1
roll % d e f g c
= % d e f g (output c)
% d e f g
**loop push index 4**
% d e f g 4
-1 % d e f g 4 -1
roll % e f g d
= % e f g (output d)
% e f g
**loop push index 3**
% e f g 3
-1 % e f g 3 -1
roll % f g e
= % f g (output e)
% f g
**loop push index 2**
% f g 2
-1 % f g 2 -1
roll % g f
= % g (output f)
% g
**loop push index 1**
% g 1
-1 % g 1 -1
roll % g
= % (output g)
%
**loop final reached**
So this little loop (and `roll` usage) lets you access the
stack bottom-to-top!