On Mar 19, 10:58 am, Jonah Thomas <jethom...@[EMAIL PROTECTED]
> wrote:
> I think I agree with you right down the line, and it sounds vaguely like
> you're disagreeing. So I want to make sure I haven't missed the point.
Probably more a difference in emphasis than a difference in substance.
> I don't need DRAW-LINE or Line or whatever its name is to be re-entrant
> because it might as well be a primitive. I'm never going to stop it in
> the middle to do another graphics word.
Yes, *however* ...
> I might do something else that's re-entrant that uses Line and I can
> save the values then. So it isn't a problem for me to use a 2VARIABLE
> instead of a double stack variable or a graphics stack etc. And if I
> want those, I can use them at a higher level than Line.
.... precisely. Using a *pair* of 2VARIABLEs (you need two points for a
well behaved turtle ... or a point and a direction/distance, which is
the same amount of state), then if there is a desire to "draw a box
around this that is this distance up and to the left from here and a
certain size, and then come back here", it can be localized *at that
point* by storing the current state, doing the side task, and then
restoring the current state. That can be:
* on the data stack
* on the return stack
* in a data structure associated with an instance of an object
* on a point stack
Indeed, the word to fetch the state of that kind of "target-point"
turtle is at the same time how to use a primitive like LINE to draw
for the turtle, since you always want to fetch first the current-pt
then the target-pt then, after book-keeping, can simply call LINE from
there.
> Since very often the place I want to start the next line is where the
> last line ended, it makes sense to keep that info in a global variable.
> For sheer esthetics I prefer as a general rule to avoid variables. but
> when they work better, why not use them? Similarly with locals.
For sheer esthetics, I prefer that variables reflect intrinsic state
of the mechanism being built, and use computations driven by those
variables to propagate the consequences, rather than determine the
consequences and post them to a range of intermediate variable.
However, for the problem at hand, if the task of generating a series
of rectangular combinations of two corner points is repeated for a
variety of primitives like LINE, then:
\ hide the stack noise inside edge generating words
: dup-points ( x1 y1 x2 y2 -- x1 y1 x2 y2 x1 y1 x2 y2 ) 2OVER 2OVER ;
: topline ( x1 y1 x2 y2 -- x1 y1 x2 y1 ) DROP OVER ;
: rightline ( x1 y1 x2 y2 -- x2 y1 x2 y2 ) >R ROT DROP TUCK R> ;
: bottomline ( x1 y1 x2 y2 -- x1 y2 x2 y2 ) ROT DROP TUCK ;
: leftline ( x1 y1 x2 y2 -- x1 y1 x1 y2 ) >R DROP OVER R> ;
: BOX3 ( x1 y1 x2 y2 -- )
dup-points topline LINE
dup-points rightline LINE
dup-points bottomline LINE
leftline LINE ;
And we see there are two factors there ... one to replace the 1st with
the 3rd, and one to replace the 3rd with the 1st:
: dup-points ( x1 y1 x2 y2 -- x1 y1 x2 y2 x1 y1 x2 y2 ) 2OVER 2OVER ;
: 1->3 ( a b c -- c b c ) ROT DROP TUCK ;
: 2->4 ( a b c d -- c b c d ) >R 1>3 R>
: 3->1 ( a b c -- a b a ) DROP OVER ;
: 4->2 ( a b c d -- a b a d ) >R 3>1 R> ;
' 3->1 ALIAS topline ( x1 y1 x2 y2 -- x1 y1 x2 y1 )
' 2->4 ALIAS rightline ( x1 y1 x2 y2 -- x2 y1 x2 y2 )
' 1->3 ALIAS bottomline ( x1 y1 x2 y2 -- x1 y2 x2 y2 )
' 4->2 ALIAS leftline ( x1 y1 x2 y2 -- x1 y1 x1 y2 )
: BOX3 ( x1 y1 x2 y2 -- )
dup-points topline LINE
dup-points rightline LINE
dup-points bottomline LINE
leftline LINE ;


|