A recent comment (Hi Andrew!) asked how I got started with PostScript.
Note that this is not a recommendation on how you should get started
with PostScript, but it worked for me.
The First Step
This all started with the Full Thrust wargame: all my good computer
learning experiences have come from having a problem that, in order to
solve, I needed to learn about something. In 2001 or so, I was working
on a ship design system for that game (for non-wargamers: you pick a
hull size, then fill it with engines, weapons, defences, and so on).
There would be three programs in the design system: one to edit
individual ships, one to combine those ships into a fleet (while
selecting individual loadouts for things that were not part of the
design but would be configured on a case by case basis, such as which
sort of fighter squadron was in each bay of a carrier), and one to
convert those fleet and ship files into something graphical. So far so
good. I would write all this in Perl with the Tk module to provide a
GUI, but I needed some way of getting a graphical output from it to
generate the sheets one would take to the table.
I thought about GD, the Perl bitmap manipulation module that I was
using at the time, but decided that using vector graphics would allow
me to have both good-looking output (smooth to the resolution of
whatever printer was used) and relatively small files.
In those days generating PDFs was (generally considered to be) Hard. I
think you pretty much had to buy Acrobat Distiller (nobody would ever
have dreamed of pirating it of course) and in any case it wasn't
available on Linux. What else could I generate programmatically, that
would give me vector graphics? PostScript!
So I started looking into it, and didn't find much. (2002, remember.
These days it would probably all be in long-forgotten YouTube videos.)
I looked around and found the PostScript Language Reference Manual,
aka the Red Book. (There are also the PostScript Language Tutorial and
Cookbook, the Blue Book, and PostScript language program design, the
Green Book, but I either didn't know about them or decided to learn
directly from the reference.) So I did a lot of trial and error
looking through the Red Book (particularly the Operators chapter,
which lists every keyword in the language by category as well as a
summary of its syntax, followed to a detailed description of each).
Also there was GhostScript, which would let me preview the PostScript
file. Because I didn't have a printer that spoke PostScript natively;
those were expensive. That was the loop: write some PostScript, then
fire up GhostScript and see how it looked.
So the program was written in Perl and would generate PostScript. The
top of the page would have the fleet name, player name, and so on; the
rest was a notional 3×2 grid of rectangles in which the ship graphicss
would fit. There was a large preamble, the "shiplib", which would go
in first and define a function to generate each component; then the
individual components would be laid out in a virtual space (pushing
weapons that fired to port to the left side of the frame, etc.) which
might take more than one of the ship rectangles if it were especially
complicated, and that virtual space would be added to the output. For
example, a class 2 K-gun firing forward-only might be added as:
0 1 0 0 0 0 (2) -20 -30 kgun
for which the first six parameters are the arcs, then the text label
with the class, then the X and Y coordinates within the virtual space.
The PostScript code is all very baby level stuff.
It worked, but people complained about having to install Perl (on
Windows this was hard) and GhostScript to use the output. Hey ho.
The software is still
available, still works
on modern Perl, and at the end of that page is an example of what the
output would look like. Getting an actual printout could be tricky,
but GhostScript usually managed. These days I would probably use
PDF::API2, or Typst, and generate a PDF directly.
Anyway, that was stage one. I thought of PostScript as an enjoyable
tool, but didn't have any other use for it.
The Second Step
Then in 2019 I started doing what was then the Perl Weekly
Challenge, and a few weeks in thought
"you know, I bet I could solve some of these problems in PostScript
too". The first one I can find in my archive is for challenge 23, and
it's still very basic; I didn't use it for every problem at first, but
by writing some PostScript in most weeks I found myself improving
rapidly. I was no longer using the graphical elements of the language
at all, except in the very rare cases when a problem called for them.
And it's still the language that feels most fun to me. It's probably
even more basic than Lua, but it's so easy to extend it that I hardly
notice. A big part of the fun is the reverse Polish syntax (parameters
first, then the function that uses them), and you don't have to (and I
largely didn't) commit fully to the stack at first: you can just
define variables, read their values or assign to them, just as you can
with most languages, and it'll still work. But there's fun to be had
in going from that to something that uses no variables at all, and
just plays with the stack. (It can be rather harder to read and debug,
though.)
By 2022 I was bored with copying in my various assistant functions
(starting, I think, with a thing to join an array of strings into a
single string with a defined separator) and started my PostScript
libraries,
including an unreleased bit of hacky Perl that will scan a program to
see which library functions it's using and drop them and their
dependencies into the code—in other words, I've written a linker! I
wanted to be able to do map and filter (grep) as I do in every
other language I write, so I added them, and other functions have been
added essentially as I needed them. Again, as in most modern
languages, a function is a thing you can pass as a parameter to
something else; so for example my filter takes an array and a
function, applies the function to every member of the array, and
returns an array consisting only of those items for which the function
returned true.
[ 1 2 3 4 5 ] { 2 mod 1 eq } filter
That function, the bit in the braces, being "take the input parameter
modulo 2, and return true if it equals 1, false otherwise". So it
returns
[ 1 3 5 ]
Should you write a project in PostScript? My goodness no! GhostScript
is relatively slow (not as slow as Raku, but nothing is as slow as
Raku) and apart from offering a slightly different way of looking at
things has little to recommend it as a general-purpose programming
language. Also what you get is very basic. But if you find you enjoy
writing toy programs in it you may want to write something slightly
bigger, and if you're producing graphics anyway why not do the
calculations in PostScript too?
You can still get the Red Book (and the others) from Adobe, but I
don't trust its URL to be stable, so I'll link to the Wikipedia
page for
PostScript instead: first item under "Further reading".