# Programming in Forth with Forth style

## Description of the page content

Some examples of Forth code written without the Forth style, and how to rewrite them.

Tags:

Sometimes I've found Forth code that is written without the Forth style. This page shows two examples, and how I rewrote them. This page is a brief version of the original article in Spanish, with step by step changes in the code.

## Example 1

In Sideras (page in Spanish), a little game written in Ace Forth by an unknown author, I found the following word:

``````: izq
x @ 0 > ascii 5 k= and
if
x c@ 1- x !
then
;
```
```

The word `k=` has the following definition (but it's not relevant for the example);

``````: k=  inkey =  ;
```
```

The word `izq` (abbreviation of "left" in Spanish) tests the 5 key and, if the player's x coord is more than zero, it is decreased.

It works... But it's not the Forth's style. Here you are my alternative:

``````: izq  x dup @ ascii 5 k= - 0 max swap !  ;
```
```

Result:

| |= original code |= new code | |= words | 15 | 11 | |= control structures | 1 | 0 | |= calculations | 2 | 1 | |= times the `x` variable is mentioned | 3 | 1 |

In Ace Forth, the result of a boolean operation is 0 or 1. In ANS Forth the result is 0 or -1 (more useful and logical), so the code would be:

``````: izq  x dup @ [char] 5 k= + 0 max swap !  ;
```
```

## Example 2

Let's see a larger example. The listing of Chase, a little game for the Jupiter Ace, was published by Andrew Curtis in Popular Computing Weekly in 1983.

### Original code

The original code is almost ilegible:

``````10 VARIABLE X
15 VARIABLE Y
1 VARIABLE A
1 VARIABLE B

: CHASE CLS 10 X ! 15 Y ! 1 A ! 1 B ! BEGIN X @ Y @ AT ."  " A @ B @ AT ."  " INKEY 53 = IF Y @ 2 - Y ! THEN INKEY 54 = IF X @ 2 - X ! THEN INKEY 55 = IF X @ 2 + X ! THEN INKEY 56 = IF Y @ 2 + Y ! THEN X @ 20 > IF 20 X ! THEN Y @ 30 > IF 30 Y ! THEN X @ 1
< IF 1 X ! THEN Y @ 1 < IF 1 Y ! THEN X @ A @ = IF Y @ B @ = IF ." GOT YOU!" 250 1000 BEEP QUIT THEN THEN X @ A @ > IF A @ 1+ A ! THEN X @ A @ < IF A @ 1– A ! THEN Y @ B @ > IF B @ 1+ B ! THEN Y @ B @ < IF B @ 1– B ! THEN X @ Y @ AT ." A" A @ B @ AT
." E" 250 70 BEEP 0 1 = UNTIL ;
```
```

In lowercase and with proper indentation, the code looks much better. It's clear the code was written with the style of BASIC: many conditionals, and many redundant calculations.

``````10 variable x
15 variable y
1 variable a
1 variable b

: chase
cls
10 x ! 15 y !
1 a ! 1 b !
begin
x @ y @ at ."  "
a @ b @ at ."  "
inkey 53 = if y @ 2 - y ! then
inkey 54 = if x @ 2 - x ! then
inkey 55 = if x @ 2 + x ! then
inkey 56 = if y @ 2 + y ! then
x @ 20 > if 20 x ! then
y @ 30 > if 30 y ! then
x @ 1 < if 1 x ! then
y @ 1 < if 1 y ! then
x @ a @ = if
y @ b @ = if
." got you!" 250 1000 beep quit
then
then
x @ a @ > if a @ 1+ a ! then
x @ a @ < if a @ 1– a ! then
y @ b @ > if b @ 1+ b ! then
y @ b @ < if b @ 1– b ! then
x @ y @ at ." A"
a @ b @ at ." E"
250 70 beep
0 1 =
until
;
```
```

### Modified code

This is my version, with no conditional structure, simplified calculations and simpler main loop:

``````10 variable x
15 variable y
1 variable a
1 variable b

: chase
cls
10 x ! 15 y !
1 a ! 1 b !
begin
x @ y @ at space
a @ b @ at space
y @ inkey 53 = 2 * - inkey 56 = 2 * + 1 max 30 min y !
x @ inkey 54 = 2 * - inkey 55 = 2 * + 1 max 20 min x !
x @ a @ = y @ b @ = and 0=
while
a @  x @ over > +  x @ a @ < negate +  a !
b @  y @ over > +  y @ b @ < negate +  b !
x @ y @ at ." A"
a @ b @ at ." E"
250 70 beep
repeat
." got you!" 250 1000 beep
;
```
```

It's almost Forth style, but not completely: Factoring is needed. Instead of one large word, many little specialized and independent words are better: the code gets easier to read and mantain.

The result of factoring the code of Chase became a new program: Heat Seeker.