Blog

From time to time I'll add announcements about my photography plugins on this page.

I've left my, now historical, thoughts on the past, present and future of printing and software below those.

There's a link to subscribe to the RSS feed below.

 RSS Feed

  1. After nearly forty years working on software for the print industry, and nearly thirty working on standards, I’ve decided that it’s time to step back and let younger and more agile minds take over.

    It’s been a lot of fun, and I’ve learned an awful lot over that time. I hope I’ve been able to pay something back to an industry that I have come to love, even as it twists and turns and changes as the world changes around it.

    So, from the end of this month my work here will be done.

    I’ll be shutting down most of my web pages over the next few weeks, although I’m kicking some ideas around that may see the site resurrected in a different guise a bit later.

    Many thanks for the support and friendship that many of you have offered me over the years.

    Thanks

    Martin Bailey

    Ps – in case you're not a geek, that fish quote is explained here.

  2. PostScript RIP

    Every year since 2015, in the run-up to Christmas, Eric Wastl runs “Advent of Code” (AoC), a site hosting a series of daily puzzles for geeks to solve by writing code. Last year I thought I’d try it and, in a moment of somewhat flippant curiosity, decided that I’d write my code in the PostScript language.

    PostScript is now, quite rightly, regarded as a legacy language in most situations, although there are still chunks of it in a number of tools related to design, prepress and printing. I’ve always thought of it as a perfectly competent general-purpose programming language, albeit one with some interesting characteristics arising from the fact that it’s not compiled and a program can therefore self-modify while it is running. And, of course, its useful ‘side effect’ or making marks on a raster that can be printed.

    But the heyday for PostScript was probably in the late 90’s and early noughties, so its perfectly possible that nobody else has ever tried AoC using it. I’d be interested to hear if you have any evidence that they have (I will admit to not doing much research on that).

    For the first week or so everything went well. As is usual in a lot of programming tasks, the biggest challenge is often to design a data structure that enables the puzzle to be solved, and to munge the incoming data stream into that format. But nothing was very hard.

    And then I hit a day where the puzzle was all about multiplying integers together several thousand times. An integer is a whole number (1, 2, 3 etc) and most computer languages, like PostScript, differentiate between those and “real numbers” (sometimes described as floating-point numbers) which can contain fractional parts as well. Most languages have a hard limit on the largest positive and smallest negative integers that they can hold. PostScript has an extra quirk in that if you try to work with an integer larger than that limit it gets automatically converted into a real number. Languages can handle a larger range of real numbers, but at the cost of less precision. If you perform a few thousand mathematical operations on a very large real number then the rounding errors caused by that lack of precision can add up quite quickly.

    The puzzle description also gave a few hints along the lines of “you’ll have to find a way to limit the size of the integers you end up with”, which I took on board, and coded in what seemed likely to be a simple but effective work-round for that.

    For the first time in AoC I typed in my answer … and it was wrong.

    It didn’t take me long to find out that I was still using larger numbers than PostScript could handle. Reworking to use a more complex, but more effective method, allowed me to complete the puzzle correctly.

    There’s an AoC subreddit where people share their solutions and code, so once I’d cracked this puzzle I went to have a look. It turns out that almost everyone had used the work-round that I’d first thought of, and it had worked for them.

    At that stage I realised why it hadn’t worked for me. PostScript only has one type of integer object, effectively a signed 32-bit integer. More accurately, the language doesn’t define the size of integer objects (and therefore their range), but the PostScript Red Book does say that interpreters are likely to have an architectural limit to 32-bits … and therefore people writing PostScript code try not to use any numbers that won’t fit into that range. In practice, that’s not a big deal, as the maximum signed 32-bit integer is 2,147,483,647; plenty large enough for most purposes.

    And, when integers get converted to real numbers, PostScript reals are effectively single precision, unlike the double precision reals used (or, at least, available) in many other languages. That means that more data is lost when a large integer is converted to a real number than would be the case with double precision.

    These limitations are not really surprising given the origins of PostScript as being written for use on resource-constrained printer control boards, and the lack of any obvious need to amend them in later language levels. But it did mean that, when I tried my original code on two different RIPs (what would be called virtual machines for many other non-compiled languages), the answer it reported was over 3 billion different between them because of rounding errors!

    Moving on to the next day, the puzzle was to find a route through a maze. I could see how to do it and wrote my code. It worked fine for the small sample data set that is provided for code validation. But when I tried it on the real, much larger, data set it just ran, and ran and ran. For over a day.

    I walked through my code, adding optimisations, which I hadn’t really bothered with to start with because this isn’t production code; it’ll only be used once (assuming it gives the right answer!) I also added debug to show that it was actually doing something. It had still been running for over a day when I pulled the plug.

    I double-checked my logic and added more debug to check that my code was returning from recursive calls correctly, and it was. I took a quick look on the subreddit to make sure I was on the right path. I was. But other people were reporting completion in a few seconds, not tens of hours.

    To be fair, the recursive nature of the problem meant that it was walking through the same code sequence billions of times, and that recursion also means that variables need to be stored in data structures instead of simple globals or leaving them on the operand stack, which takes more time.

    So, strike number two: PostScript is not high performance for massive amounts of computation. Again, not really a huge surprise, as I assume that was not in the design goal when it was created.

    At that point I got overtaken by family issues, and then by work, so I decided to drop out for 2022. Maybe I’ll come back in 2023 … but not with PostScript!

    In conclusion: PostScript is not a bad programming language in the context for which it was designed. But it’s nothing like as general, or as efficient as a whole variety of more recent languages.

    As I said above, there are still products with chunks of PostScript inside them, and that’s not a bad thing. Those code blocks don’t probe the limits of integer ranges, and they don’t perform billions of computations.