| 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://news.ycombinator.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://news.ycombinator.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://news.ycombinator.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!) |
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.