appear superficially similar, since both languages use a mostly postfix-based syntax (see PostfixNotation
). Since Forth predates PostScript
by quite a few years, PostScript
is often assumed to be descended from Forth.
According to JohnWarnock?
, inventor of PostScript
, this is not the case.
- Postscript is a graphical page description language invented by ChuckGetsche? and JohnWarnock? (the President and CEO of Adobe). Its syntax looks a little bit like Forth, because it is derived from Forth; however, Postscript's internal implementation has nothing to do with Forth. (from http://www.google.com/search?q=cache:sysadmin.habitue.net/html/v05/i07/a6.htm+postscript+forth+John+Warnock&hl=en ).
states in the preface to 'PostScript
Language Reference Manual' (1st Edition): "Although the Design System language and its successors bear a superficial resemblance to the Forth programming language, their conception and development were entirely independent of Forth."
"Does not contain code from forth" does not mean "is not descended from forth". C is considered to belong in the Algol family even though it doesn't contain code from an implementation of Algol. PostScript
wouldn't be what it is without forth.
It seems to me that Forth is to stacks what LispLanguage
is to lists. Forth demonstrated the advantages of a stack-centric paradigm in which each pushed or popped item could be evaluated as an expression or a primitive. Postscript reflects the application of that paradigm to the world of typography, 2-d graphics, and page layout. My own recollection is that Postscript's primary contribution was the use of splines to describe character glyphs, allowing them to be effectively rendered at virtually any resolution desired. If anything, Postscript owes more to TexLanguage
than to Forth. I view the stack-based language paradigm as a convenient afterthought rather than a central organizing principle.
I also think we should note the contribution that OwenDensmore?
, at Sun, made in demonstrating how to use Postscript dictionaries to create a dynamically-bound object-oriented runtime environment. This was the fundamental premise of the Sun window server that ultimately became the NetworkExtensibleWindowSystem
. Owen and I discussed his "crazy" idea at a poolside table at the now-demolished Hyatt Palo Alto, on El Camino. I told him that it made sense to me, we scribbled furiously on napkins, and I helped him see how he might adopt some learnings from Smalltalk. It was one of those afternoons that could only have happened at that time in that place in that culture. -- TomStambaugh
I've extracted Owen Densmore's paper from the news.tape.tar (marked PD), "Object Oriented programming in NeWS", and uploaded it: http://code.google.com/p/xpost/downloads/detail?name=monterey86.pdf
It would require some modification to run in other postscript environments, but not much, I think. It was developed after the 1st Edition Postscript manual but before the second, so it's considered a Level 1.5 Postscript environment. It uses dictionaries freely, but the << /Level-2 (syntax) >> had not yet been invented. So it uses a number of nonstandard operators for dictionary construct. These would need to be simulated or the routines rewritten to use Level 2 syntax. -- luserdroog
I think the "because it is derived from Forth"
statement says a lot. ;-> he is talking about the syntax, not the implementation and conception
I've generally described Postscript as "FORTH, with an impressive rendering library."
The rendering library seems to be independent of FORTH.
But the core language (sans library) seems like FORTH to me.
The precise genealogical relationship appears to be mildly controversial, however, some things are crystal clear:
- Postscript is "Forth-like"; the two share many features, enough so that it wouldn't be unreasonable to call Postscript a "Forth-family" language, even if it turned out it was invented 100% independently (which itself is apparently not the case).
- Forth uses two stacks (aside from rare exotic variants). Postscript uses 5 stacks, the code stack, the data stack, the dictionary stack, the graphics context stack, and the snapshot restore stack (the latter is usually left out of the count, so usually people say it has 4 stacks, but that's merely because that 5th stack is an implicit rather than explicit requirement; an ultra-slow Postscript can avoid that 5th stack, but cannot run most Postscript programs at reasonable speed. And it wasn't described in the language reference; one has to infer it as a requirement in order to have a reasonable implementation)
- The Postscript dictionary stack is a true innovation in language design, although not often discussed as such. It allows explicit and dynamic manipulation of name scoping rules without need to change the language implementation, which allows for "mini-languages" to be easily created with non-default scoping rules to suit individual programs or even individual functions. This creates a power that is similar in flavor to that provided by Lisp macros, although by no means directly related to Lisp macros.
- It is also the means by which fonts are stored and used in Postscript programs. Even if one philosophically prefers not to fiddle with scoping rules when programming in general, it turns out to be undeniably very powerful to do in the context of finding an appropriate font by scoping or explicit selection.
- The Postscript snapshot restore stack is an extremely efficient and easy to implement way to do memory allocation that allows some of the same benefits of garbage collection, without the complexity that a truly fast GC algorithm entails. It isn't as general as GC, so Postscript eventually added GC to the language (first in Display Postscript/NeWS, later in regular Postscript).
- But it also is a very powerful way to cleanup once a subtask has completed. In most languages a destructor needs to have explicit code to undo any temporary changes that were made to a resource shared with a superclass (in Postscript, one of the primary shared resources is "the current page"). The Postscript mechanism allows one to simply take a snapshot (one ultra-cheap function call) just before calling some mechanism that may (or may not) make changes to shared resources, and then call restore-snapshot after that mechanism is finished. In typical cases the restoration happens very quickly, and in any case, is automatic...individual destructors don't have to get their logic right.
- Any Forth could be extended to have the same matrix arithmetic and line drawing and spline functions etc that Postscript has, but of course it makes a differernce that they are standard in Postscript.
- Beyond that, the precise way that the pieces fit together in the Forth language model to facilitate rendering pages is very, very elegant and innovative, although each little piece was not invented for Postscript. The default coordinate matrix, switching from the page coordinate system to the character box coordinate system, the calls that drawstring makes, the save and restore of graphics context -- it would take a lengthy description, but I've never seen it done so well anywhere else.
There's more to say about Postscript (and Forth), but that's just off the top of my head (I've implemented interpreters for both languages).
One should note that PostScript
isn't the first time a postfix language has been invented independently from Forth. The JoyLanguage
came upon it from the FunctionalProgramming
direction. Discovering many of the same stack operators (named differently) and adding other operators which make more sense in a functional language.