Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

In what way is PostScript worse than Forth? Please answer with specific details, and provide links to code if you can. I programmed a lot of Forth code before learning and moving on to programming a lot of PostScript code, so I've used each of them extensively, and much prefer PostScript, and I'm happy to show you why and explain by showing you code.

PostScript is much higher level than Forth, and a lot more like Lisp than Forth, and has much better data structures than Forth, like polymorphic arrays (that can be used as code), dictionaries (that can be used as objects), strings, floating point numbers, and NeWS "magic dictionaries" that can represent built-in objects like canvases, processes, events, fonts, etc.

Yet Forth doesn't even have dynamically allocated memory, although in a few pages of code you can implement it, but it's not standard and very few Forth libraries use it, and instead use the linear Forth dictionary memory (which is terribly limited and can't be freed without FORGETting everything defined after you allocated it):

https://donhopkins.com/home/archive/forth/alloc.f

PostScript is homoiconic. Like Lisp, PostScript code IS first class PostScript data, and you can pass functions around as first class objects and call them later.

https://en.wikipedia.org/wiki/Homoiconicity

PostScript lets you define local variables with names in dictionaries, and use stacks of those dictionaries as objects and classes, while Forth requires you to keep track of everything on the stack without giving it a name. Forth variables are effectively globals. The fact that PostScript is homoiconic means you can write PostScript functions that dynamically create and transform other PostScript functions, like Lisp macros.

In October 1986, before I ever used NeWS or learned of Owen Densmore's Smalltalk-like PostScript object system, I had just used PostScript on the LaserWriter and invented my own simple object system like Lisp Machine Flavors (which was quite easy and obvious) for drawing pie menus, I wrote the following to Mitch Bradley comparing Forth and PostScript. (Mitch was the Forth guru at Sun who developed ForthMacs / Sun Forth / CForth / Open Firmware / etc -- I worked with him at Sun on Forth as his summer intern, then later with James Gosling at Sun on NeWS as a full time employee):

https://github.com/MitchBradley

https://donhopkins.com/home/archive/forth/forth-postscript.t...

>After having programmed in PostScript for some time, how do you feel about its relation to Forth? Have your feelings about Forth changed any?

>They are somewhat different languages, suitable for different applications, but there is a lot of overlap, however. There are features and problems that each has that the other lacks. I have thought a lot about doing in PostScript some of the things one can do in Forth, as well as Lisp.

>In writing the code for the PieMenus on the Laser Writer, I had to come up with some way to make objects, not unlike flavors. It would also be interesting to make objects in the manner of <builds and does>. Objects are obviously implemented as dictionaries. Instance variables and messages are just bindings in the dictionary. The question is how do you build the dictionaries?

>You can have PostScript functions that build them by hand, or you can have it more data driven. (Not to say that PostScript functions aren't data. Weee!) But how do you represent the data? You want to specify defaults when creating a class, and values when instantiating objects.

>Should the creation of classes and objects be the same operation? (As with XLisp.) The required instance variable values could be taken as arguments when instantiating an object of some class, and the optional ones

>How about object instantiation consuming required values? right off the stack? How would inheritance work? By concatinating dictionaries, or by nesting them?

>It sure doesn't take much code to do this stuff. This is because PostScript has a very general set of building blocks for just such things.

PostScript makes it easy to efficiently implement a flexible dynamic object oriented programming system like Smalltalk's, with multiple inheritance, and prototype objects that you can dynamically promote both methods and instance variables from classes to instances. Tom Stambaugh described how Smalltalk inspired Owen Densmore's PostScript object oriented system in NeWS:

https://hackertimes.com/item?id=18696116

>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 and DonaldKnuth 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:

https://ia802600.us.archive.org/5/items/pdfy-1U9Ry1_Qj0LPSR6...

Like Lisp or Scheme, you can easily write a metacircular PostScript evaluator in a few pages of PostScript:

https://hackertimes.com/item?id=21968842

>Also, here is a metacircular PostScript interpreter, ps.ps: a PostScript interpreter written in PostScript! Since PostScript is homoiconic and so much like Lisp, it was as easy as writing a metacircular Lisp interpreter (but quite different in how it works, since PostScript and Lisp have very different execution models).

https://www.donhopkins.com/home/code/ps.ps.txt

https://donhopkins.com/home/archive/psiber/cyber/ps.ps.reaso...

    Obvious Question:
      Why would anybody ever write a PostScript interpreter in PostScript?

    Possible Answers:
      To use as a debugging tool.
      To trace and single step through the execution of PostScript code.
      To serve as a basis for PostScript algorithm animation.
      To gain a deeper understanding of how PostScript works.
      To try out some ideas from Structure and Interpreteration.
      To experiment with extensions to the PostScript language.
      To demonstrate that PostScript isn't just for breakfast any more.
      To make PostScript run even slower (but thicker).
      To avoid programming in C (the portable assembly language of the 80's).
      To use to interpret its self.
      To have something nerdish to talk about at parties.
And you can use NeWS PostScript to implement a visual programming system and debugger to itself:

https://medium.com/@donhopkins/the-shape-of-psiber-space-oct...

NeWS not only supported multiple loadable toolkits, but it had "packages" to keep them safely separated and modularized so clients could request whatever versions of whatever toolkits they needed, and the same code and data would be properly shared between all compatible clients. (See "findpackage" / "beginpackage" at the beginning of every X11/NeWS program, like this X11 window manager for NeWS implemented in PostScript:)

https://www.donhopkins.com/home/archive/NeWS/owm.ps.txt

In case you would rather program in a Lisp-like syntax than PostScript, David Singer and Rafael Bracho at Schlumberger wrote ListScript, a Lisp to PostScript compiler:

https://donhopkins.com/home/archive/NeWS/NeScheme.txt

>PostScript is often compared to Forth, but what it lacks in relation to Forth is a user-extensible compiler. You can write your own PostScript control structures and whatnot, like case and cond, to which you pass procedures as arguments on the stack, but the PostScript scanner is not smart -- but there is no preprocessing done to the PostScript text being read in, like the way immediate words in Forth can take control and manipulate the contents of the dictionary and stack while the text source is being read in and compiled, or like the way Lisp macros work. This is one of the things I would like to be able to do with something like LispScript.

And in case you are suffering from poor taste in programming languages, and you don't like Lisp but would rather program in a C- or Java-like syntax than PostScript, Arthur van Hoff at the Turing Institute wrote PdB, an object oriented C to PostScript compiler, which let you subclass PostScript classes in PdB, and also subclass PdB classes in PostScript:

https://hackertimes.com/item?id=21968842

>And later on around 1990-1993, Arthur van Hoff wrote PdB at the Turing Institute in Glasgow, an object oriented C to PostScript compiler called PdB (for Pure dead Brilliant), which is kind of like TypeScript, conceptually. We used PdB to develop HyperLook (Networked PostScript based HyperCard for NeWS), which I used to port SimCity to NeWS on Unix. (A few years after that, Arthur wrote the Java compiler in Java at Sun in 1995, and lot of other cool stuff since then!)



Here is an example of making Lisp-like macros with PostScript, using a technique like "backquote", to compile PostScript code templates into more efficient drawing functions, and promote customized dynamically generated code into the instances (NeWS had a prototype based object system that made that possible).

This is a design document I wrote for Open Look Sliders for The NeWS Toolkit 2.0.

https://www.donhopkins.com/home/archive/NeWS/tnt-sliders-des...

* THE PROBLEM:

The tNt 1.0 slider implementation was a subclass of ClassDialControl, which was a subclass of ClassControl. It needed to be reimplemented, directly as a subclass of ClassCanvas (with ClassTarget mixed in), and had to be taught to play games with the services architecture, and brought in line with the controls architecture. All that hot air from the collapse of the ParentDictArray had to go somewhere, so the slider was graphically "puffed up" with a fake 3-D look. It is hoped that the result of this transfer of energy will result in a net decrease in size and increase in speed. To cope with the increase in complexity of drawing special effects, a form of inlining or macro expansion similar to "backquote" in lisp was used, to promote fast drawing procedures into slider instances.

* DESIGN CHOICES:

space/time tradeoffs The backquote technique speeds up drawing but takes up space. But the macro templates (defined as methods that are inlined and promoted) can still be executed even if they haven't been promoted. There is a small hit for executing "," which is defined as "/, {exec} def" (since it can't be defined as "/, /exec load def" because of autobind). And of course the templates are slower than the their inlined promoted expansions, because they're calculating the values each time instead of just pushing constants. Right now, the promotion happens upon /reshape, when the size is known and the layout can be calculated. Another space saving trade-off might be to only expand and promote the macros at the start of tracking, during which parts of the control must be frequently repainted, and unpromote it upon completion of tracking.


Here's the PdB object oriented C to PostScript compiler and lots of other NeWS stuff:

https://github.com/IanDarwin/OpenLookCDROM/blob/master/NeWS/...

https://github.com/IanDarwin/OpenLookCDROM/tree/master/NeWS/...

https://github.com/IanDarwin/OpenLookCDROM/tree/master/NeWS

Also a paper by Arthur van Hoff about "Syntactic Extensions to PdB to Support TNT Classing Mechanisms":

https://www.donhopkins.com/home/archive/NeWS/PdB.txt

More LispScript stuff (compiling Lisp to PostScript):

https://www.donhopkins.com/home/archive/NeWS/NeScheme.txt

And to compare some window management tasks in Forth and PostScript:

X10 window manager in Forth:

https://www.donhopkins.com/home/code/fuwm-main.forth.txt

X11 window manager in PostScript:

https://www.donhopkins.com/home/archive/NeWS/owm.ps.txt

NeWS tabbed pie menu window manager in PostScript for TNT 2.2 (which "owm" could wrap around X-Windows):

https://www.donhopkins.com/home/archive/NeWS/tab-3.0.2.ps.tx...

NeWS Tab Window Demo: Demo of the Pie Menu Tab Window Manager for The NeWS Toolkit 2.0.

https://www.youtube.com/watch?v=tMcmQk-q0k4


Thanks for all this stuff, some of which I wish I'd been aware of at the time, like LispScript.

I don't remember the details, like how it was used, but I recall the metacircular evaluator in HyperNeWS (or do I mean HyperLook?) being called out as a (the?) major pain point in the system for speed of the interpreter.


I wrote a metacircular evaluator, ps.ps, but I only used it in PSIBER for debugging (single stepping through code, which the normal PostScript interpreter didn't support directly, and also drawing visualizations of code execution). So the fact that it was slow wasn't really an issue, since it wasn't used in any speed critical situation.

https://www.donhopkins.com/home/code/ps.ps.txt

Nether GoodNeWS aka HyperNeWS aka HyperLook nor TNT (The NeWS Toolkit) used a metacircular evaluator themselves.

HyperLook could copy the image of windows to the clipboard as a PostScript drawing, but didn't need to use "PostScript capture" for that [below], because it represented drawings in its own format as a display list of PostScript data, that PostScript code interpreted to draw, and when you printed an image, it would just send a header with the drawing interpreter to the printer, followed by the drawing data and a call to the interpreter.

Maybe it was the speed of the structured drawing interpreter that people were complaining about. There is some overhead of course, but it's washed out by the fact that actually performing the drawing itself takes much more time than interpreting the data.

Or maybe you're thinking of "PostScript capture", which is effectively "partial evaluation" of arbitrary PostScript code, with respect to the imaging model (making paths, filling and stroking them, and rendering text)? You can efficiently implement PostScript capture without resorting to a metacircular evaluator, simply be redefining a few key operators like "fill", "stroke", "show", etc.

https://en.wikipedia.org/wiki/Partial_evaluation

PostScript capture is the technique of executing some arbitrary PostScript code that produces a drawing (which could be a traditional document in a PostScript file meant for the printer, or even a window system object like a menu), and capturing the drawing commands as another PostScript program, without any computation, conditionals, and loops. It would capture the effects of the drawing commands as another simple, flat PostScript program with all the conditionals and loops unwound (so a small recursive drawing procedure would produce an enormous flat drawing file, but most normal documents would be optimized to be smaller and even print faster), in the same global coordinate system, with unnecessary graphics state changes removed.

That's the essence of Adobe Acrobat's "Distiller", or Glenn Reid's "PostScript Distillery". I wrote distill.ps "in the spirit of Glenn Reid's Distillery" for PSIBER, and the NeWS Toolkit had its own /capture method built in, but they weren't actually used for much besides making a few illustrations.

https://medium.com/@donhopkins/the-shape-of-psiber-space-oct...

>Printing Distilled PostScript

>The data structure displays (including those of the Pseudo Scientific Visualizer, described below) can be printed on a PostScript printer by capturing the drawing commands in a file.

>Glenn Reid’s “Distillery” program is a PostScript optimizer, that executes a page description, and (in most cases) produces another smaller, more efficient PostScript program, that prints the same image. [Reid, The Distillery] The trick is to redefine the path consuming operators, like fill, stroke, and show, so they write out the path in device space, and incremental changes to the graphics state. Even though the program that computes the display may be quite complicated, the distilled graphical output is very simple and low level, with all the loops unrolled.

>The NeWS distillery uses the same basic technique as Glenn Reid’s Distillery, but it is much simpler, does not optimize as much, and is not as complete.

Here's more about the metacircular interpreter and distilled PostScript:

https://hackertimes.com/item?id=13705664

>What you've described sounds exactly like a PostScript interpreter! You can easily write a metacircular PostScript interpreter in PostScript!

http://www.donhopkins.com/home/psiber/cyber/ps.ps.txt

>And here is a PostScript quine:

    {{[ exch /dup load /exec load ] cvx} dup exec}
>If you wanted to produce "safe" PostScript file for printing, that used a standard header file and didn't require a Turing complete printer with loops, conditionals, functions, etc, you could write a partial evaluator for PostScript that projects it against the stencil-paint imaging model, optimizes the graphics, and prints out another "safe" PostScript program using a standard header, with all the loops unrolled and conditionals evaluated and functions called and graphics in the same coordinate system. That would enable you to capture anything you draw on the screen, independent of the PostScript algorithmic procedures and classes and libraries and application required to draw it.

http://www.donhopkins.com/home/psiber/cyber/distill.ps.txt

>Glenn Reid, who also wrote books on PostScript like Thinking in PostScript, pioneered that idea in his "PostScript Language Distillery", which is the idea that grew into PDF.

http://donhopkins.com/home/archive/postscript/newerstill.ps....

Glenn tells me that the PostScript distillery was actually John Warnock's idea!


Sir, this is an Olive Garden.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: