Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conklin E.K.Forth programmer's handbook.2000.pdf
Скачиваний:
321
Добавлен:
23.08.2013
Размер:
2.04 Mб
Скачать

Forth Programmer’s Handbook

dead.beef

All literal numbers should have a preceding h# (for hex) or d# (for decimal). The only exception is in tables, where the number base is explicitly specified. For example:

hex

create foo

1234 , abcd , 56ab , 8765 ,

0023 , ...

6.3 WONGS RULES FOR READABLE FORTH

Following is a set of rules for readable Forth posted in comp.lang.forth by:

Leo Wong (hello@albany.net)

New York State Department of Civil Service

Albany, NY 12239

with additional commentary by Wil Baden, including quotes from Leo Brodie (author of the popular tutorial Starting Forth; see Appendix A Bibliography). These rules are not provided here as definitive guidelines—they are presented in order to provoke thought about which approaches may be most useful in your own programming practice.

1.Use the word that fits the data.

2.Do not use ASCII codes (or other “magic numbers”) in colon definitions.

3.Do not factor just to factor.

4.Get all three right: code, comment, and name.

5.Do not use syntactic sugar.

6.Eschew sophistication.

7.Test it, even if it’s obvious.

8.Do not shun Scylla by falling into Charybdis*.

9.Feature the stack machine.

*In the Odyssey, the mighty Ulysses was required, at one point, to sail through a strait that was guarded on one side by the many-headed monster Scylla, and on the other by Charybdis, the whirlpool of oblivion. Many sailors tried so hard to avoid the one that they succumbed to the other.

Programming Style 191

Forth Programmer’s Handbook

10.Pattern names after other names.

These rules are not for beginners learning their Forth ABCs, but might be helpful to a person who has written a program and wants to make it clearer.

6.3.1 Example: Magic Numbers

Here are some examples:

: STAR

42 EMIT ;

: STAR

." *" ;

: STAR

[CHAR] * EMIT ;

Each of these definitions has a fault:

!The first forces the reader to know that ASCII 42 means * (although this could be remedied by a comment).

!The second uses a word intended for strings.

!The third is wordy in the source, although it compiles the same result as the first.

I don’t consider the lack of a stack comment in these definitions a fault. I find the third STAR to be the most readable and, hence, preferable.

Two rules:

1.Use the word that fits the data.

2.Do not use ASCII codes or other unidentified numbers in colon definitions.

6.3.2 Example: Factoring

From the first edition of Starting Forth (p. 43):

: QUARTERS 4 /MOD . ." ONES AND " . ." QUARTERS " ;

From the second edition (p. 40):

192 Programming Style

 

 

 

 

Forth Programmer’s Handbook

: $>QUARTERS

 

( dollars --

quarters dollars) 4 /MOD ;

: .DOLLARS

(

dollars -- )

.

." dollar bills" ;

: .QUARTERS

 

( quarters --

)

. ." quarters " ;

: QUARTERS

(

dollars -- )

 

 

$>QUARTERS

." Gives " .DOLLARS ." and " .QUARTERS ;

In the second edition, a name and two stack comments are wrong (as is the output, not shown here). In addition, this approach is both larger and slower without contributing significantly to readability or functionality.

Rules:

3.Do not factor just to factor.

4.Get all three right: code, comment, and name.

6.3.3 Example: Simplicity

Two solutions adapted from Starting Forth, 2nd edition (pp. 277–278):

(1)

: bdot"

BRIGHT R>

COUNT 2DUP + >R

TYPE

-BRIGHT ;

: B."

POSTPONE bdot"

[CHAR] " WORD

C@ 1+

ALLOT ;

IMMEDIATE

 

 

 

Brodie: “The foregoing solution is messy and probably not transportable.”

[Note: transportability is limited by the assumptions this approach makes about the implementation]

(2)

: B." POSTPONE BRIGHT POSTPONE ." POSTPONE -BRIGHT ; IMMEDIATE

Brodie: “The disadvantage of this solution over the previous one is that every invocation of B." compiles two extra addresses. The first solution is more efficient and therefore preferable if you have the system source listing and lots of invocations of B.". The second solution is simpler to implement, and adequate for a small number of invocations.

Programming Style 193

Forth Programmer’s Handbook

“Other languages may be easier to learn; but what other languages let you extend the compiler like this?”

An alternative that doesn’t include the compilation features might be:

: .BRIGHT ( a u) BRIGHT TYPE -BRIGHT ;

Rules:

5.Do not use syntactic sugar.

6.Eschew sophistication.

6.3.4 Example: Testing Assumptions

In Thinking Forth (reprint edition, p. 219), Brodie quotes Moore:

“In books you often see a lot of piece-wise linear approximations that fail to express things clearly. For instance the expression

x = 0 for t < 0 x = 1 for t ≥ 0

“This would be equivalent to:

t 0< 1 AND

“as a single expression, not a piece-wise expression.”

Rule:

7. Test it even if it’s obvious.

6.3.5 Example: IF Avoidance

Forth programmers strive to avoid IF, some going so far as to use CASE whenever possible. Here are two examples, from Starting Forth, of IF-avoidance:

194 Programming Style

Forth Programmer’s Handbook

First the IF versions (second edition, p. 183):

: CATEGORY

( weight-per-dozen -- category#)

DUP 18 < IF

0

ELSE

DUP 21

< IF

1

ELSE

DUP 24

< IF

2

ELSE

DUP 27

< IF

3

ELSE

DUP 30

< IF

4

ELSE

 

 

5

 

THEN THEN THEN THEN THEN SWAP DROP ;

(Note: the “official table” on which CATEGORY is based is ambiguous. See p. 85.)

: LABEL

(

category# --

)

 

DUP

0=

IF

."

Reject "

ELSE

DUP 1 =

IF

."

Small

"

ELSE

DUP 2 =

IF

."

Medium "

ELSE

DUP 3 =

IF

."

Large

"

ELSE

DUP 4 =

IF

."

Extra

Large "

ELSE

 

 

 

 

." Error "

 

THEN THEN THEN

THEN THEN DROP ;

Now the “simple and elegant for experts” versions (pp. 189 and 253):

CREATE

SIZES

18

C,

21 C,

24 C, 27 C, 30 C, 255 C,

: CATEGORY

( weight-per-dozen -- category# )

6 0

DO

DUP

 

SIZES I + C@

 

< IF

DROP

I

LEAVE

THEN

LOOP ;

CREATE

"LABEL"

 

 

 

 

 

ASCII " STRING Reject

Small

Medium Large Xtra LrgError "

: LABEL

(

category# -- )

 

8 *

"LABEL"

+

8 TYPE SPACE ;

: LABEL

 

0 MAX

5

MIN

LABEL ;

It may seem unfair of me to give the code without the explanations, but:

!Experts wouldn’t need the explanations.

!I would have to mention the bugs in the elegant LABEL. Which versions would you rather maintain?

Programming Style 195

Соседние файлы в предмете Электротехника