Back in the early 1980s John Warnock, the founder of Adobe, had invented
PostScript. He'd pioneered all their work of getting a PostScript interpreter
embedded into laser printers. He persuaded Steve Jobs, at the time, to say: "When your
new Macintosh comes out we want it to be almost a dual announcement - at the same
time". But they didn't quite make it. The Macintosh did come out, first of all
- the little 9-inch [screen] one, that we've done videos on but alongside it, fairly shortly
afterwards was the Apple laser printer. John had got the "killer app.", he thought, to
show off the skills and wonder of his laser printer driving, with PostScript,
the output. And that killer example was a United States Income Tax form for
Supplementary Income. So he programmed this up in his PostScript language. You
sent it down to the Apple Laserwriter which was so fast you couldn't believe it (!)
But it took a minute and a quarter to image it. And the wondrous Jobs, of
course, said: "John I know how to present but I cannot hold them [the audience] for one minute
and a quarter while we press the button and we wait for it to come out. And the light
at the front [of the Laserwriter] is going blink, blink, blink"! So John, being a very good computer
scientist and knowing all about his own language, PostScript, said: "Yeah, what we've
got to do, Steve, is remove all the procedures, just get them automatically
removed and unroll the loops and make sure that every 'if' statement that we
know what data goes into that 'if' statement so we know which way it's
going to go through the program. So we're going to flatten the program - as it's sometimes called.
We're going to linearize it; we're going to bind in the data and say: "We want the fastest route
to the final visual effect". So that's what he did and the unrolled version
imaged in 20 seconds - not a minute and a quarter. So it really did work.
We teach our students very carefully good programming principles. We teach
them to use 'if' statements 'for' loops blocks, structured programming.
Oh! and above all else isn't it nice to hive stuff off into procedures or
subroutines - whatever you want to call them. And to call them up with suitable arguments.
It's clean and nice and structured and gets you very good grades in your coursework.
Under the hood you always have to remember that there is a bit of a
penalty, performance-wise, to be paid for doing all this. If you just consider the
humble 'for' loop, for example. Every time you go round that loop the compiler is
building in a checking mechanism, at the top, saying: "You said start at one and in
steps of 1 go on until you get to 6. And do it around the loop like that. And
every time we go in that loop it has to say 'What's my loop counter at the moment
Oh! I'm on three. Now, let me take a look at how far I'm supposed to -- oh! 6.
Is three less than six. Yes it is!
Oh! I think we'd better go round again". I exaggerate - but you know what i'm
getting at. Equally if you dive into a procedure and you call it up with arguments
do remember - from what we've done already - that that causes stack frames to be set up to
propel your arguments to that function and to post them into the function and
then when the function has finished doing its job
it has to clear down that stack frame. And if the function is recursive there
might be the zillions of stack frames to be cleared down.
It's all overhead, but it's overhead that you're probably prepared to pay
because it helps you think about the problem and do it neatly and elegantly.
But, if you're concerned with performance of your program to the nth degree,
these overheads can begin to tell and sometimes to get the optimum/maximum
performance, under specialist conditions, you might want to say: "Rather than going
around this 'for' loop six times and doing pretty well exactly the same
thing, I will write it out, by hand, six times and forget the 'for' loop". Would that
be quicker? The answer is, very often, "Yes".
What I thought I'd do, in the true spirit of Computerphile - this little
example that we'll do now - we want to print out six Computerphile banners. Look
at that! Correct fonts and everything! As you all know it's called OCR-A. I'm afraid
that my printer is a bit deficient. It's knocked off the corner of the pointy bracket
- but please forgive.
OK - so how do we do it just using a PostScript 'for' loop?
Well, very briefly, I'll go through this with you. More details available on the
specialist PostScript video if you need it. Every PostScript program has to start
with %! This says I am PostScript from now on
Comments in PostScript programs begin with % in column 1. So [here is] a program for six
Computerphile banners. Define the variable 'n' to be 6. Here is the PostScript command
called 'selectfont' which says what font you want and what point size do you want
to do it at.
We're saying: "Find the font called OCR-A and, at point size 30, make me a copy of
that ready for use in PostScript. Here
PostScript does everything backwards in Reverse Polish notation, but effectively
it is very simple.
It's a 'for' loop so it's basically saying: for - starting at one and in steps of one up to 'n'
(but we know 'n' is 6) do the following code inside these curly braces. Now the
next line is saying we want six "Computerphiles" and they should all be at 10 points
in from the margin and they should be a 100 points apart. When you look at
this carefully I'm doing them upwards, not downwards. Now you can see what happens
when you start printing out stuff, probably designed for US Letter, on to A4
paper. Your 10 point. - what is it, 72 points an inch? I tried to do a
one-seventh of an inch indent and it didn't work!
It's all to do with paper sizes but anyway, going up the page, it's a
100-point increments which is just a bit more than an inch. Six
instances of "Computerphile" all beautifully printed out. And there's the
end of your 'for' loop. And finally it has - as it were - virtually imaged this for
you inside its own graphic memory. But if you wanted it to show up on your screen, or
ultimately an your piece of paper, you say 'showpage'. Now some PostScript interpreters,
if it gets to end of file and you haven't said 'showpage' will put a 'showpage' in for you. There's the 'showpage'.
Here's the thing done,
not in a 'for' loop but writing out six separate calls of the command to print
out "Computerphile" at 30 point. You might say: "Well you used things like 'show'
and 'moveto' and 'showpage' and here, on this copy, you're not! No, I'm trying to
show you something which will be of use to us later on -- that PostScript enables
you to redefine operators and to abbreviate their names if you want to.
So, up at the top here I say: "Look
define, just the letter 's', to be the operator 'show'. Define 'm' to be the same
as 'moveto'. Now the word 'bind' just means: "Remember I've done this definition and
don't permit any other redefinitions that might mess things up. Don't let
anybody .... above all don't let even yourself - making mistakes - try and change it again."
This is binding solidly 'm' to being 'moveto. 'selectfont' I've abbreviated as
'sf'; 'showpage' as 'sp'. And look the very first one is there that's "10 200 moveto" and
there, and then another, then another and finally 'sp' which is the abbreviation for
'showpage'. But I didn't write it out by hand - I got a "transform" program to do
it for me. Because it's all right doing six of these with a bit of fancy abbreviation
definitions at the top. But if it was 10,000 times round I don't want to
replicate something 10,000 [times] in an editor, or by hand.
Here's a "transform" script which we'll leave there for in the notes. So if you get
it working write us a comment will you? And say: "Yeah! Wow! it worked for me".
You should be able to work out how to use it. And i should say this is a much, much,
much simplified version of the unrolled "transform" script that John Warnock used
back in 1984 to get his income tax form - which was far more
complicated than six "Computerphiles", to print out in a reasonable amount of time
on the Apple Laserwriter. Just one final comment. What John did and what this is
echoing here in this abbreviation .... "Why are you bothering to abbreviate?" The
answer is: "Well, if you unroll the loops and replicate things, you're making files
bigger and bigger and bigger". Lots more printing isn't there, in the file, and
that's not necessarily a good thing.
Can we keep file size down? Yes, by doing abbreviations. And that realization, made
by John in 1984, was the very earliest glimmerings of what we now know as PDF.