Remember the Simplicity of BASIC’s Graphics Commands?

LINE (x1,y1)-(x2,y2),color
LINE (x1,y1)-(x2,y2),color,B
LINE (x1,y1)-(x2,y2),color,BF

Some Variants You Probably Didn’t Know About

LINE -(x2,y2),color[,B[F]]
LINE - STEP (dx2,dy2),color[,B[F]]
LINE STEP (dx1,dy1) - (x2,y2),color[,B[F]]
LINE STEP (dx1,dy1) - STEP (dx2,dy2),color[,B[F]]

Compare with Graphics APIs in C, et. al.

/* This example is for AmigaOS, since I
 * know it best.  Demonstrates how to
 * LINE (0,0)-(639,199),1 in BASIC.
 */

RastPort *rp = ... ;
/* ... */
SetAPen(rp, 1);
SetFgMode(rp, JAM1);
SetLineMode(rp, 0xFFFF);
MoveTo(rp, 0, 0);
DrawTo(rp, 639, 199);

Compare with Graphics APIs in C, et. al.

Solution 1: Discrete Entry Points for Each Combination

void lineNear_displacedBy_inColor_(dx1, dy1, dx2, dy2, color);
void rectNear_displacedBy_inColor_(dx1, dy1, dx2, dy2, color);
void boxNear_displacedBy_inColor_(dx1, dy1, dx2, dy2, color);
void lineNear_to_inColor_(dx1, dy1, x2, y2, color);
void rectNear_to_inColor_(dx1, dy1, x2, y2, color);
void boxNear_to_inColor_(dx1, dy1, x2, y2, color);
void lineFrom_displacedBy_inColor_(x1, y1, dx2, dy2, color);
void rectFrom_displacedBy_inColor_(x1, y1, dx2, dy2, color);
void boxFrom_displacedBy_inColor_(x1, y1, dx2, dy2, color);
void lineFrom_to_inColor_(x1, y1, x2, y2, color);
void rectFrom_to_inColor_(x1, y1, x2, y2, color);
void boxFrom_to_inColor_(x1, y1, x2, y2, color);
/* ... etc ... */

Solution 2: If You Use OO, You Can Use Fluent Interfaces

Draw.new.from(x1,y1).offsetBy(dx2,dy2).inColor(5).line();

Much easier!!

What’s Happening?!

Draw.new.from(x1,y1).offsetBy(dx2,dy2).inColor(5).line();

What’s Happening?!

Draw.new.from(x1,y1).offsetBy(dx2,dy2).inColor(5).line();

What are Fluent Interfaces, Really?

What are Fluent Interfaces, Really?

Fluent Interfaces in Forth

Fluent Interfaces in Forth

Fluent Interfaces in Forth

Fluent Interfaces in Forth

Fluent Interfaces in Forth

Fluent Interfaces in Forth

Fluent Interfaces in Forth

VOCABULARY DRAW-DSL
\ . . . etc . . .
PREVIOUS

VARIABLE fp
5 CELLS CONSTANT /frame

: draw   fp @ ,  HERE fp !  /frame ALLOT
         DRAW-DSL ;

Fluent Interfaces in Forth

DRAW-DSL DEFINITIONS
: fp.x1               fp @ ;
: fp.y1               fp @ [ 1 cells ] literal + ;
: fp.x2               fp @ [ 2 cells ] literal + ;
: fp.y2               fp @ [ 3 cells ] literal + ;
: fp.clr              fp @ [ 4 cells ] literal + ;

Fluent Interfaces in Forth

DRAW-DSL DEFINITIONS
: from ( x y -- )     fp.y1 !  fp.x1 ! ;
: offsetFrom ( ... )  fp.y1 @ + fp.y1 !  fp.x1 @ + fp.x1 ! ;
: to ( x y -- )       fp.y2 !  fp.x2 ! ;
: offsetTo ( dx dy )  fp.y1 @ + fp.y2 !  fp.x1 @ + fp.x2 ! ;
: inColor ( clr -- )  fp.clr ! ;

Fluent Interfaces in Forth

DRAW-DSL DEFINITIONS
: _line ( -- )        ( bresenham's algorithm ) ;
: _box ( -- )         ( draw y2-y1 number of horizontal lines ) ;
: _rect ( -- )        ( draw four orthogonal lines ) ;

: done                /frame CELL+ NEGATE ALLOT  HERE @ fp !  PREVIOUS ;
: line ( -- )         _line  done ;
: box ( -- )          _box   done ;
: rect ( -- )         _rect  done ;

Fluent Interfaces in Forth

: hline   draw
            fp.x1 @ OVER from  fp.x2 @ swap to  fp.clr @ inColor
          line ;

: _box    fp.y2 @  fp.y1 @
          BEGIN   2DUP XOR
          WHILE   DUP hline  1+
          REPEAT ;

Fluent Interfaces in Forth

E.g,

draw 0 0 from 639 199 offsetTo 5 inColor line

Fluent Interfaces in Forth

: offsetTo ( dx dy )  fp.y1 @ + fp.y2 !  fp.x1 @ + fp.x2 ! ;
: hline   draw
            fp.x1 @ OVER from  fp.x2 @ over to  fp.clr @ inColor
          line ;

: _box    fp.y2 @  fp.y1 @
          BEGIN   2DUP XOR
          WHILE   DUP hline  1+
          REPEAT ;

Revisiting LINE in Forth

LINE (0,0)-(10,10),1

draw 0 0 from 10 10 to 1 inColor line

LINE (0,0)-(10,10),1,B

draw 0 0 from 10 10 to 1 inColor rect

LINE (0,0)-(10,10),1,BF

draw 0 0 from 10 10 to 1 inColor box

LINE (0,0)-STEP(10,10),1

draw 0 0 from 10 10 offsetTo 1 inColor line

LINE (0,0)-STEP(10,10),1,B

draw 0 0 from 10 10 offsetTo 1 inColor rect

LINE (0,0)-STEP(10,10),1,BF

draw 0 0 from 10 10 offsetTo 1 inColor box

LINE STEP(0,0)-(10,10),1

draw 0 0 offsetFrom 10 10 to 1 inColor line

LINE STEP(0,0)-(10,10),1,B

draw 0 0 offsetFrom 10 10 to 1 inColor rect

LINE STEP(0,0)-(10,10),1,BF

draw 0 0 offsetFrom 10 10 to 1 inColor box

. . .

. . .

Fin!

Thank you!

Q & A