Final exhortation: GO FORTH now and create masterpieces of digital typography!

With respect to the directions of the route

I may have made some errors.

” FRAY PEDRO FONT, Diary (1776)

The road to wisdom? Well, it™s plain

and simple to express:

Err

and err

and err again

but less

and less

and less.

” PIET HEIN, Grooks (1966)

(page 232)

A

Answers to

All the

Exercises

Appendix A: Answers to All the Exercises 233

The preface to this manual points out the wisdom of trying to ¬gure out each whatever

dir

exercise before you look up the answer here. But these answers are intended to

be read, since they occasionally provide additional information that you are best

equipped to understand when you have just worked on a problem.

2.1. Point 5 = (100, 0) is closer than any of the others. (See the diagram below.)

2.2. False. But they all do have the

same y coordinate.

(Figure A2a will be inserted here; too bad you

2.3. 5 units to the left of the reference can™t see it now.)

point, and 15 units up.

2.4. (200, ’60).

2.5. top lft z1 = (0, b); top z2 = (a, b); top rt z3 = (2a ’ 1, b); bot lft z4 = (0, 0);

bot z5 = (a, 0); bot rt z6 = (2a ’ 1, 0). Adjacent characters will be separated by exactly

one column of white pixels, if the character is 2a pixels wide, because the right edge of

black pixels is speci¬ed here to have the x coordinate 2a ’ 1.

2.6. right = (1, 0); left = (’1, 0); down = (0, ’1); up = (0, 1).

2.7. True; this is (2, 3) ’ (5, ’2).

2.8. 0[z1 , z2 ] = z1 , because we move none of the way towards z2 ; similarly 1[z1 , z2 ]

simpli¬es to z2 , because we move all of the way. If we keep going in the same direction

until we™ve gone twice as far as the distance from z1 to z2 , we get to 2[z1 , z2 ]. But if

we start at point z1 and face z2 , then back up exactly half the distance between them,

we wind up at (’.5)[z1 , z2 ].

2.9. (a) True; both are equal to z1 + 1 (z2 ’ z1 ). (b) False, but close; the right-hand

2

side should be 2 z1 + 1 z2 . (c) True; both are equal to (1 ’ t)z1 + tz2 .

3 3

2.10. There are several reasons. (1) The equations in a program should

represent the programmer™s intentions as directly as possible; it™s hard to understand

those intentions if you are shown only their ultimate consequences, since it™s not easy

to reconstruct algebraic manipulations that have gone on behind the scenes. (2) It™s

easier and safer to let the computer do algebraic calculations, rather than to do them

by hand. (3) If the speci¬cations for z1 and z5 change, the formula ( 1 [x1 , x5 ], b) still

2

gives a reasonable value for z3 . It™s almost always good to anticipate the need for

subsequent modi¬cations.

However, the stated formula for z3 isn™t the only reasonable way to proceed.

We could, for example, give two equations

x3 ’ x1 = x5 ’ x3 ; y3 = b;

the ¬rst of these states that the horizontal distance from 1 to 3 is the same as the

horizontal distance from 3 to 5. We™ll see later that is able to solve a wide

variety of equations.

2.11. The following four equations su¬ce to de¬ne the four unknown quantities x2 ,

y2 , x4 , and y4 : z4 ’ z2 = whatever — dir 20; 1 [y2 , y4 ] = 2 [y3 , y1 ]; z2 = whatever [z1 , z3 ];

2 3

z4 = whatever [z3 , z5 ].

234 Appendix A: Answers to All the Exercises

3.1. The direction at z2 is parallel to the line z4 . . z3 , but the vector z4 ’ z3 drawdot

speci¬es a direction towards z4 , which is 180—¦ di¬erent from the direction z3 ’ z4 that one point

“

was discussed in the text. Thus, we have a di¬cult speci¬cation to meet, and - curl

draws a pretzel-shaped curve that loops around in a way that™s too ugly to

show here. The ¬rst part of the path, from z4 to z2 , is mirror symmetric about the

line z1 . . z5 that bisects z4 . . z2 , so it starts out in a south-by-southwesterly direction;

the second part is mirror symmetric about the vertical line that bisects z2 . . z3 , so

when the curve ends at z3 it™s traveling roughly northwest. The moral is: Don™t specify

a direction that runs opposite to (i.e., is the negative of) the one you really want.

3.2. draw z5 . . z4 {z4 ’ z2 } . . z1 . . z3 . . z6 {z2 ’ z6 } . . cycle.

4.1. (a) An ellipse 0.8 pt tall and 0.2 pt wide (˜ ™); (b) a circle of diameter 0.8 pt

(rotation doesn™t change a circle!); (c) same as (a).

4.2. Six individual points will be drawn, instead of lines or curves. These points will

be drawn with the current pen. However, for technical reasons explained in Chapter 24,

the draw command does its best work when it is moving the pen; the pixels you get

at the endpoints of curves are not always what you would expect, especially at low

resolutions. It is usually best to say ˜drawdot™ instead of ˜draw™ when you are drawing

only one point.

4.3. True, for all of the pens discussed so far. But false in general, since we will see

later that pens might extend further upward than downward; i.e., t might be unequal

to b in the equations for top and bot .

4.4. x2 = x1 ; x3 = 1 [x2 , x4 ]; x4 = x5 ; bot y1 = ’o; top y2 = h + o; y4 = y2 ;

2

y5 = y1 ; draw z1 . . z2 ; draw z2 . . z3 ; draw z3 . . z4 ; draw z4 . . z5 . We will learn

later that the four draw commands can be replaced by

draw z1 - - z2 - - z3 - - z4 - - z5 ;

in fact, this will make run slightly faster.

4.5. Either say ˜¬ll z5 . . z4 . . z1 . . z3 . . z6 . . z5 . . cycle™, which doubles point z5

and abandons smoothness there, or ˜¬ll z5 {curl 1} . . z4 . . z1 . . z3 . . z6 . . {curl 1}cycle™.

In the latter case you can omit either one of the curl speci¬cations, but not both.

4.6. After the six original points have been de¬ned, say

¬ll z5 . . z4 . . z1 . . z3 . . z6 . . cycle;

z0 = (.8[x1 , x2 ], .5[y1 , y4 ]);

for k = 1 upto 6: zk = .2[zk , z0 ]; endfor

un¬ll z5 . . z4 . . z1 . . z3 . . z6 . . cycle.

1

[North , 1 [North , West ]] = 1 [90, 1 [90, 180]] = 1 [90, 135] = 112.5.

4.7. 2 2 2 2 2

4.8. 30—¦ , 60—¦ , 210—¦ , and 240—¦ . Since it™s possible to add or subtract 360—¦ without

changing the meaning, the answers ’330—¦ , ’300—¦ , ’150—¦ , and ’120—¦ are also correct.

4.9. z1l = (25, 30), z1r = (25, 20).

4.10. He said ˜penstroke z1e {up } . . z2e {left } . . z3e {down } . . z4e {right } . . cycle™.

Appendix A: Answers to All the Exercises 235

4.11. We use angles perpendicular to (w, h) and (w, ’h) at the diagonal endpoints: perpendicular

S

x1l = x4l = 0; direction

trial path

x2 = x5 = .5w; perpendicular

x3r = x6r = w;

y1r = y2 = y3l = h;

y4r = y5 = y6l = 0;

z1 = .25[z1 , z6 ]; z6 = .75[z1 , z6 ];

theta1 := angle(w, ’h) + 90;

penpos1 (b, theta1 ); penpos6 (b, theta1 );

z7 = .5[z1 , z6 ]; penpos7 (.6b, theta1 );

penpos1 (b, theta1 ); penpos6 (b, theta1 );

penstroke z1e . . z1 e {z6 ’ z1 } . . z7e . . {z6 ’ z1 }z6 . . z6e ;

e

z3 = .25[z3 , z4 ]; z4 = .75[z3 , z4 ];

theta3 := angle(’w, ’h) + 90;

penpos3 (b, theta3 ); penpos4 (b, theta3 );

z8 = .5[z1 , z6 ]; penpos8 (.6b, theta3 );

penpos3 (b, theta3 ); penpos4 (b, theta3 );

penstroke z3e . . z3 e {z4 ’ z3 } . . z8e . . {z4 ’ z3 }z4 . . z4e ;

e

penpos2 (b, 0); penpos5 (b, 0); penstroke z2e . . z5e .

5.1. The width is 0.8em#, and an em# is 10 true points, so the box will be exactly

8 pt wide in device-independent units. The height will be 7 pt. (And the depth below

the baseline will be 0 pt.)

5.2. 8 — 3.6 = 28.8 rounds to the value w = 29; similarly, h = 25. (And d = 0.)

5.3. Here™s one way, using a variable slab to control the pen breadth at the ends

of the stroke:

slab#:=.8pt#; define_blacker_pixels(slab);

beginchar("S",5/9em#,cap#,0); "The letter S";

penpos1(slab,70); penpos2(.5slab,80);

penpos3(.5[slab,thick],200); penpos5(.5[slab,thick],210);

penpos6(.7slab,80);

penpos7(.25[slab,thick],72);

x1=x5; y1r=.94h+o;

x2=x4=x6=.5w; y2r=h+o; y4=.54h; y6l=-o;

x3r=.04em; y3=.5[y4,y2];

x5l=w-.03em; y5=.5[y4,y6];

(Figure A5a will be inserted

.5[x7l,x7]=.04em; y7l=.12h-o; here; too bad you can™t see it

path trial; trial=z3{down}..z4..{down}z5; now.)

pair dz; dz=direction 1 of trial;

penpos4(thick,angle dz-90);

penstroke z1e..z2e{left}..z3e{down}

..z4e{dz}..z5e{down}..z6e{left}..z7e;

penlabels(1,2,3,4,5,6,7); endchar;

Notice that the pen angle at point 4 has been found by letting construct

a trial path through the center points, then using the perpendicular direction. The

letters work reasonably well at their true size: ˜ .™

236 Appendix A: Answers to All the Exercises

5.4. After an “isolated expression,” thinks it is at the end of a state- zero

enormous number

ment or command, so it expects to see a semicolon next. You should type, e.g.,

backslash

˜I; mode_setup™ to keep happy. begingroup

save

5.5. Yes. endgroup

1

6.1. (a) No, the second token represents 65536 . (A token has the same meaning

as ˜0™ if and only if its decimal value is strictly less than 2’17 = .00000 76293 94531 25.)

1

(b) Yes; both tokens represent 65536 , because 1 is the nearest integer to both .00001 —

2

65536 = .65536 and 0.00002 — 65536 = 1.31072. (c) No, 0.00003 represents 65536 .

(d) Yes, they both mean “enormous number that needs to be reduced”;

complains in both cases and substitutes the largest legal numeric token. (Rounding

1

4095.999999 to the nearest multiple of 65536 yields 4096, which is too big.)

6.2. xx , 3.1 (a numeric token), .6 (another numeric token), .. , [[ , a ,

+- , bc d , e , ] , ] , "a %" (a string token), <|> , ( (see rule 5), ( , $ , 1 (a

numeric token), 5 (likewise numeric), "+-" (a string token), and "" (a string token

that denotes an empty sequence of characters). All of these tokens are symbolic unless

otherwise mentioned. (Notice that four of the spaces and two of the periods were

deleted by rule 1. One way to verify that ¬nds precisely these tokens is to

prepare a test ¬le that says ˜isolated expression;™ on its ¬rst line and that contains

the stated text on its second line. Then respond to ™s error message by

repeatedly typing ˜1™, so that one token is deleted at a time.)

6.3. The statement is basically true but potentially misleading. You can insert any

number of spaces between tokens without changing the meaning of a program, but you

cannot insert a space in the middle of any token without changing something. You can

delete spaces between tokens unless that would “glue” two adjacent tokens together.

6.4. False. It may seem that this new sort of numeric token would be recognized

only in cases where the period is not followed by a digit, hence the period would be

dropped anyway by rule 1. However, the new rule would have disastrous consequences

in a line like ˜draw z1..z2™ !

7.1. You can put a space between the subscripts, as in ˜a1 5™. (We™ll see later that

a backslash acts as a null symbol, hence ˜a1\5™ is another solution.)

7.2. No; a[-1] can™t be accessed without using [ and ]. The only other form of

subscript is numeric token , which can™t be negative. (Well, strictly speaking, you

could say ˜let ?=[; let ??=]™ and then refer to ˜a?-1??™; but that™s cheating.)

7.3. Assuming that ˜+™ was still a spark when he said ˜let plus=+™, he can™t refer

to the variable ˜a.plus1™ unless he changes the meaning of plus again to make it a tag.

(We will eventually learn a way to do this without permanently clobbering plus, as

follows: ˜begingroup save plus; a.plus1 endgroup™.)

7.4. True. (But a su¬x is not always a variable .)

7.5. Yes, because it removes any existing value that x may have had, of whatever

type; otherwise you couldn™t safely use x in a numeric equation. It™s wise to declare

numeric variables when you™re not sure about their former status, and when you™re

sure that you don™t care what their previous value was. A numeric declaration together

with a comment also provides useful documentation. (Incidentally, ˜numeric x™ doesn™t

a¬ect other variables like ˜x2™ or ˜x.x™ that might be present.)

Appendix A: Answers to All the Exercises 237

7.6. (a) The ˜42™ is illegal because subscripts must be collective. (b) The ˜24™ is **

FORTRAN

illegal because a declared variable must start with a symbolic token , not a numeric

or

token. (c) There™s nothing wrong with the consecutive commas; the second comma ¡

begins a declared variable , so it loses its former meaning and becomes a tag. Thus ¿

accuracy

tries to declare the variable ˜,t,path™. However, ˜path™ cannot appear in

a su¬x, since it™s a spark. (Yes, this is admittedly tricky. Computers follow rules.)

8.1. ((z1+z2)..((z3/4)*5))..(z6-(7*(8z9))).

8.2. The fraction 100/3 is evaluated ¬rst (because such divisions take precedence);

the rounding error in this fraction is then magni¬ed by 100.

8.3. A sqrt takes precedence over any operation with two operands, hence the

machine computes ˜(sqrt 2)**2™; was somewhat lucky that the answer

turned out to be exactly 2. (The sqrt operation computes the nearest multiple of

1

, and the rounding error in this quantity is magni¬ed when it is squared. If you try

65536

sqrt 3**2, you™ll get 3.00002; also sqrt 2**4 turns out to be 4.00002.) Incidentally,

the ** operation of plain has the same precedence as * and /; hence

˜x*y**2™ means the same as ˜(x*y)**2™, and ˜-x**2™ means ˜(-x)**2™, contrary to the

conventions of FORTRAN.

8.4. Since ˜or™ has stronger precedence than ˜<™ or ˜>™, tries to eval-

uate this expression by putting things in parentheses as follows: ˜(0 > (1 or a)) < a™.

Now ˜1 or a™ makes no sense, because ˜or™ operates only on booleans; in such cases

uses the right operand ˜a™ as the result. Then ˜0 > a™ is indeterminate

because a is unknown; treats this as false. Finally ˜false < a™ is another

illegal combination of types.

8.5. The token ˜++-™ is unde¬ned, so it is a tag; therefore ++-7 is a subscripted

variable, which was multiplied by zero.

8.6. The associative law is valid for exact computations, but not for rounded com-

putations. For example, it fails even in the case of multiplication, since (.1 — .1) — 10 =

0.09995 while .1 — (.1 — 10) = .1 when products are rounded to the nearest multiples

1

of 65536 . However, this observation doesn™t quite explain the stated example, which

would have yielded 7 in all cases if √ had computed 2 ++ 4 with full accu-

racy! The closest approximation to 20 is 4 65536 , but 2 ++ 4 turns out to be 4 30941

30942

65536

instead. computes the absolutely best possible approximations to the true

answers when it does multiplications, divisions, and square roots, but not when it does

Pythagorean operations.

8.7. It™s impossible to make an expression from ˜ numeric token numeric token ™,

because the rule for scalar multiplication operator speci¬cally prohibits this. -

will recognize the ¬rst ˜2™ as a numeric primary , which is ultimately regarded

as a numeric expression ; the other ˜2™ will probably be an extra token that is ¬‚ushed

away after an error message has been given.

8.8. If a numeric token is followed by ˜/ numeric token ™ but not preceded by

˜ numeric token /™, the syntax allows it to become part of an expression only by us-

ing the ¬rst case of numeric token primary . Therefore ˜1/2/3/4™ must be treated as

˜(1/2)/(3/4)™, and ˜a/2/3/4™ must be treated as ˜a/(2/3)/4™.

238 Appendix A: Answers to All the Exercises

8.9. string primary ’’ string variable rotated

| string token dotprod

abs

| ( string expression ) ypart

| substring pair expression of string primary pythagorean subtraction

unitvector

string secondary ’’ string primary length

string tertiary ’’ string secondary

string expression ’’ string tertiary

| string expression & string tertiary

(The full syntax in Chapter 25 includes several more varieties of string primary that

haven™t been hinted at yet.)

9.1. (a) Point 1 should lie nine pixels to the left of point 7, considering horizontal

positions only; no information is given about the vertical positions y1 or y7 . (b) Point 7

should sit directly above or below point 4, and its distance up from the baseline should

be halfway between that of points 4 and 5. (c) The left edge of the currently-picked-up

pen, when that pen is centered at point 21, should be one pixel to the right of its right

edge when at point 20. (Thus there should be one clear pixel of white space between

the images of the pen at points 20 and 21.)

9.2. (a) y13 = ’y11 (or ’y13 = y11 , or y13 + y11 = 0). (b) z10 = z12 + (mm , ’1).

(c) z43 = 1 [(0, h), (w, ’d)].

3

9.3. (a) z1 = z2 = z3 = (w, h); z4 = z5 = z6 = (0, 0). (b) z1 = z6 = (.5w, .5h);

z2 = (.75w, .75h); z3 = (w, h); z4 = (0, 0); z5 = (.25w, .25h).

9.4. z = whatever [z1 , z2 ]; z = whatever [z3 , z4 ]. (Incidentally, it™s interesting

to watch this computation in action. Run with \tracingequations:=

tracingonline:=1 and say, for example,

z=whatever[(1,5),(8,19)]; z=whatever[(0,17),(6,1)];

the solution appears as if by magic. If you use alpha and beta in place of the whatevers,

the machine will also calculate values for alpha and beta .)

9.5. z = whatever [z1 , z2 ]; z ’ z3 = whatever — (z5 ’ z4 ).

9.6. z11 ’ z12 = whatever — (z13 ’ z14 ) rotated 90, assuming that z13 ’ z14 is known.

(It™s also possible to say ˜(z11 ’z12 )dotprod(z13 ’z14 ) = 0™, although this risks over¬‚ow

if the coordinates are large.)

9.7. One solution constructs the point z4 on z2 . . z3 such that z4 . . z1 is per-

pendicular to z2 . . z3 , using ideas like those in the previous two exercises: ˜z4 =

whatever [z2 , z3 ]; z4 ’ z1 = whatever — (z3 ’ z2 ) rotated 90™. Then the requested dis-

tance is length(z4 ’ z1 ). But there™s a slicker solution: Just calculate

abs ypart((z1 ’ z2 ) rotated ’angle(z3 ’ z2 )).

9.8. It would be nice to say simply ˜z = whatever [z2 , z3 ]™ and then to be able to

say either ˜length(z ’ z1 ) = l™ or ˜z ’ z1 = (l, 0) rotated whatever ™; but neither of the

second equations is legal. (Indeed, there couldn™t possibly be a legal solution that has

this general ¬‚avor, because any such solution would determine a unique z, while there

are two points to be determined.) The best way seems to be to compute z4 as in the

previous exercise, and then to let v = (l +’+ length(z4 ’ z1 )) — unitvector(z3 ’ z2 ); the

desired points are then z4 + v and z4 ’ v.

Appendix A: Answers to All the Exercises 239

9.9. Such an equation tells us nothing new about a or b. Indeed, each use of whatever

CAPSULE

whatever introduces a new independent variable, and each new independent variable

capsule

“uses up” one equation, since we need n equations to determine the values of n un- hash hash

knowns. On the other hand an equation between pairs counts as two equations; so tracingcapsules

there™s a net gain of one, when whatever appears in an equation between pairs.

10.1. Yes, but it must be done in two steps: ˜numeric newcode ; newcode = code +1;

numeric code ; code = newcode ™.

10.2. The assignment ˜x3 := whatever ™ does exactly what you want.

10.3. The result shows that s1 = s3 = s4 and s2 = s5 = s6 now:

s[]=unknown string

s1=unknown string s3

s2=unknown string s6

s3=unknown string s4

s4=unknown string s1

s5=unknown string s2

s6=unknown string s5

(The assignment s2 := s5 broke s2 ™s former relationship with s1 , s3 , and s4 .)

10.4. The results are

## a=1

(after the ¬rst assignment)

## a=b+1

(after the second assignment)

## b=0.5a-0.5

(after the third assignment)

### -1.5a=-%CAPSULEnnnn-0.5

(after the third, see below)

## a=%CAPSULEnnnn

(after ˜show™; variable a is independent)

>> a

(this is the ¬nal value of b)

>> 0.33333a-0.33333

Let ak denote the value of a after k assignments were made. Thus, a0 = 1, and a1

was dependent on the independent variable b. Then a1 was discarded and b became

dependent on the independent variable a2 . The right-hand side of the third assignment

was therefore a2 + b. At the time a2 was about to be discarded, had two

dependencies b = 0.5a2 ’ 0.5 and κ = 1.5a2 ’ 0.5, where κ was a nameless “capsule”

inside of the computer, representing the new value to be assigned. Since κ had a

higher coe¬cient of dependency than b, chose to make κ an independent

variable, after which ’1.5a2 was replaced by ’κ ’ 0.5 in all dependencies; hence b was

equal to 0.33333κ ’ 0.33333. After the third assignment was ¬nished, κ disappeared

and a3 became independent in its place. (The line ˜## a=%CAPSULEnnnn™ means that

a was temporarily dependent on κ, before κ was discarded. If the equation a = κ had

happened to make κ dependent on a, rather than vice versa, no ˜##™ line would have

been printed; such lines are omitted when a capsule or part of a capsule has been made

dependent, unless you have made tracingcapsules > 0.)

11.1. Almost, but not quite. The values of standard dimension variables like pt

and mm will be identical in both setups, as will the values of ad hoc dimension

variables like em and x height . But pen-oriented dimensions that are de¬ned via

de¬ne blacker pixels will be slightly di¬erent, because cheapo mode has blacker =

240 Appendix A: Answers to All the Exercises