Here's some stuff I wrote about a HyperCard-inspired system called HyperLook (nee HyperNeWS (nee GoodNeWS)) and some stuff I developed with it:
SimCity, Cellular Automata, and Happy Tool for HyperLook (nee HyperNeWS (nee GoodNeWS))
HyperLook was like HyperCard for NeWS, with PostScript graphics and scripting plus networking. Here are three unique and wacky examples that plug together to show what HyperNeWS was all about, and where we could go in the future!
https://medium.com/@donhopkins/hyperlook-nee-hypernews-nee-g...
Some highlights:
The Three Axis of AJAX, Which NeWS Also Has To Grind!!!
NeWS was architecturally similar to what is now called AJAX, except that NeWS coherently:
…(drum roll)…
1) Used PostScript CODE instead of JavaScript for PROGRAMMING.
2) Used PostScript GRAPHICS instead of DHTML and CSS for RENDERING.
3) Used PostScript DATA instead of XML and JSON for DATA REPRESENTATION.
The Axis of Eval: Code, Graphics and Data
We will return to these three important dimensions of Code, Graphics and Data as a recurring theme throughout this article. But which way to go from here?
Alan Kay on NeWS:
“I thought NeWS was ‘the right way to go’ (except it missed the live system underneath). It was also very early in commercial personal computing to be able to do a UI using Postscript, so it was impressive that the implementation worked at all.” -Alan Kay
What’s the Big Deal About HyperCard?
"I thought HyperCard was quite brilliant in the end-user problems it solved. (It would have been wonderfully better with a deep dynamic language underneath, but I think part of the success of the design is that they didn’t have all the degrees of freedom to worry about, and were just able to concentrate on their end-user’s direct needs."
"HyperCard is an especially good example of a system that was “finished and smoothed and documented” beautifully. It deserved to be successful. And Apple blew it by not making the design framework the basis of a web browser (as old Parc hands advised in the early 90s …)" -Alan Kay
PostScript is an amazing programming language for describing scalable graphics and interfaces! I especially enjoy the ability to very concisely represent information, using dedicated PostScript facilities to construct domain-specific languages, and I have used it to illustrate many situations that would otherwise be quite difficult to show.
I hope that an example can illustrate this point: In Volume 4 of The Art of Computer Programming, Donald Knuth explains how we can find kernels with maximum weight in C_{100}, the cycle graph with 100 nodes. In that example, the weight he assigns to each node is the Thue-Morse code, i.e., (-1)^ν, where ν is the number of occurrences of 1 in the binary encoding of the node number. So for example, the weight of node 2 is -1, and the weight of node 3 is 1.
We can easily determine the Thue-Morse weight of an integer in PostScript:
Example: 8 weight ⇒ -1
Now, how might we compactly lay out the cycle graph with 100 nodes? Using PostScript lets us easily play with different layouts. For example, let us use r, u, l and d to move right, up, left and down, respectively:
We can see what the described path looks like by interpreting this mini-language:
Now, we only have to draw the nodes themselves on top of this path. First, let us define which nodes are actually part of a kernel with maximum weight, found with the methods outlined by Knuth (operations on reduced and ordered Binary Decision Diagrams):
And now we can simply draw the nodes by interpreting the instructions again, and indicating whether a node is part of the kernel, and whether its weight is positive:
In this case, I am using circles for nodes with positive weight.
The beauty of your functional approach is that you're using PostScript code as PostScript data, thanks to the fact that PostScript is fully homoiconic, just like Lisp! So it's excellent for defining and processing domain specific languages, and it's effectively like a stack based, point free or "tacic," dynamically bound, object oriented Lisp!
https://en.wikipedia.org/wiki/Homoiconicity
https://en.wikipedia.org/wiki/Tacit_programming
The PostScript dictionary stack enables OOP with multiple inheritance and customizable instances (like prototypes, in that you can add methods and instance variables to individual objects).
https://donhopkins.com/home/monterey86.pdf
>Object Oriented Programming in NeWS. Owen M. Densmore, Sun Microsystems. Abstract
>The NeWS window system provides the primitives needed to create window managers and user-interface toolkits, but does not, itself, supply either. This is done to achieve a layering strategy for building several higher level systems that can share NeWS as their low level window system. None of the traditional ‘‘tool kit’’ solutions currently span the diverse set of clients NeWS needed to serve; they simply lack sufficient flexibility. We are exploring an object oriented approach which uses a flexible inheritance scheme. This paper presents our initial attempt at introducing a Smalltalk style class mechanism to PostScript, and our first use of it.
Apps like (early versions of) Adobe Illustrator, and tools like Glenn Reid's PostScript Distillery (and later Acrobat Distiller), used a domain specific subset of PostScript as their save file format: A save file was a domain specific language that just happened to be PostScript (with no loops or other programming constructs), so you could prepend some standard PostScript function definitions to the front of the save file and send it to a PostScript printer to print. Or you could redefine those names to do something else, like extracting the text, or cataloging the colors, or creating interactive editable objects that you could manipulate and save out again.
Distillery (and the later Acrobat Distiller) went the other way, by partially interpreting any arbitrary PostScript drawing program against the stencil/paint imaging model (capturing a flat list of calls to fill and stroke, transforming the paths to a standard coordinate system, optimizing graphics state changes between rendering calls, unrolling all loops, and executing any conditionals, loops, function calls or other programming constructs). That's exactly what happens when you convert a PostScript file to PDF.
https://en.wikipedia.org/wiki/Partial_evaluation
https://en.wikipedia.org/wiki/Meta-circular_evaluator
Acrobat is the (purposeful) de-evolution of PostScript from a Turing complete programming language to a safe static file format: PDF is essentially just PostScript without any of the programming constructs. (But then they added a lot more crap to it, to the point that it was so buggy they needed to push out patches several times a month over many years.)
Here's some more stuff about PostScript distilleries and metacircular PostScript interpreters (but with old links, so I've included the new one below):
https://news.ycombinator.com/item?id=13705664
Thanks to PostScript's homoiconicity, a PostScript data visualizer/browser/editor just happens to also be a PostScript code visualizer/browser/editor!
https://medium.com/@donhopkins/the-shape-of-psiber-space-oct...
>The Shape of PSIBER Space: PostScript Interactive Bug Eradication Routines — October 1989 Written by Don Hopkins, October 1989. University of Maryland Human-Computer Interaction Lab, Computer Science Department, College Park, Maryland 20742.
>Left shows objects on the process’s stack displayed in windows with their tabs pinned on the spike. Right shows a Pseudo Scientific Visualization of the NeWS rootmenu instance dictionary.
>Abstract: The PSIBER Space Deck is an interactive visual user interface to a graphical programming environment, the NeWS window system. It lets you display, manipulate, and navigate the data structures, programs, and processes living in the virtual memory space of NeWS. It is useful as a debugging tool, and as a hands on way to learn about programming in PostScript and NeWS.
>[...] 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.
Yikes, am I reading this right? That PostScript here is implied as a good thing? Here is xeyes implemented in PostScript. It was probably better than the X Windows implementation of the era, but compared to JavaScript... I shudder.
https://groups.google.com/forum/#!original/comp.windows.news...
Well, given that you notice that it "was probably better than the X Windows implementation of the era" it looks like you are in some sense reading this right but are nevertheless making a comparison to a language with many decades worth of modernization improvements, for some unclear reason.
well, it looks frankly beautiful. The code is 100% declarative. It's a pure dataflow graph, right before your eyes. Sure, the syntax feels old, but the ideas beneath will always be the ones underneath reactive and user interface programming.
Here's the PostScript source code to PizzaTool, which shipped with OpenWindows 3.0 and Solaris 2.0 (SVR4), which is well commented and organized so you can follow what's going on:
https://donhopkins.com/home/archive/NeWS/pizzatool
And the manual entry:
https://donhopkins.com/home/archive/NeWS/pizzatool.6
More on the sordid history of PizzaTool and the Window System Wars at Sun Microsystems:
https://medium.com/@donhopkins/the-story-of-sun-microsystems...
This is a taste of what multi threaded object oriented PostScript code looks like:
That's 93 lines of PostScript code, including comments. And how many lines of C code is XEyes? (Not including the Makefile.am, autogen.sh, configure.ac, and other supporting cruft, to be charitable. I'm counting xeyes.c (141), Eyes.c (642), Eyes.h (56), EyesP.h (56), transform.c (111), transform.h (32), eyemask.bit (22), eyes.bit (22) = 1082 lines of really ugly code -- not easy on the eyes!)
http://cgit.freedesktop.org:80/xorg/app/xeyes/snapshot/xeyes...
By the way, XEyes was a later imitation of Jeremy Huxtable's original NeWS "Big Brother" eyes.
https://web.archive.org/web/20140228084012/http://en.wikiped...
Here's a much more elaborate version of NeWS eyes, that lets you drag and drop eyes into each other (see "MoveStopSub"), nesting them to any depth (so child eyes recursively move around with their parent eye, and look really creepy), and split eyes in two with a menu (see "SplitEye"), in 375 lines of PostScript code:
https://donhopkins.com/home/archive/NeWS/eyes.ps
Have you ever actually used the X11 SHAPE extension to make a round window, did you know all X11 windows actually have FOUR shapes (client bounding region, client clip region, effective bounding region, effective clip region), and do you understand all the nuances and implications of the ICCCM ("Ice Cubed") window management protocol?
https://en.wikipedia.org/wiki/Shape_extension
https://www.x.org/releases/current/doc/libXext/shapelib.html
https://blog.dshr.org/2018/05/recreational-bugs.html
"You will get a better Gorilla effect if you use as big a piece of paper as possible." -Kunihiko Kasahara, Creative Origami.
And what is the net speed velocity of an XConfigureWindow request?
https://medium.com/@donhopkins/the-x-windows-disaster-128d39...
Apples and Oranges. Postscript itself includes the code for the primitives used in xeyes, whereas the C code implements them first. Take away that code and it is much more illuminating.
Are you saying that HTML Canvas should not have a method to draw circles because you can implement a circle drawing algorithm in JavaScript?
What is your point? That it's a liability that PostScript has a far superior, more powerful, scalable, device independent, future proof, and vastly more convenient and easier to use and understand imaging model than X11?
And by the way, NeWS eyes came first: "xeyes" was a lower quality knock-off, not the original. The first version of "xeyes" actually used a rectangular window, which kind of missed the whole point, until somebody added hundreds of lines of extremely complex code to implement the SHAPE extension. I linked to the source above: download and read it if you don't believe me.
NeWS lets you shape a round (or any shape) window the exact same way you draw the same shape. See how pizzatool shapes the spinning full or half circle pizza window floating inside a rectangular frame, so you can easily move and resize it:
So it looks like this:
https://donhopkins.com/home/catalog/images/pizzatool.gif
But with X-Windows you have to bend over backwards manipulating pixmaps or lists of rectangles, so the window shaping code is completely different and much more complex than the drawing code.
Case in point: take a look at the "ShapePieMenu" function in the Tk pie menus I implemented for X11/TCL/Tk SimCity, for another example of how much of a pain in the ass it is to shape a window in X11. It has to first get the display and query to make sure the extension is supported, then if it is, make the window exist, get the window id, make a pixmap, make a graphics context, set the foreground color, erase the background, set the foreground color, fill a bunch of rectangles, free the graphics context, and call XShapeCombineMask. And that's only shaping the window to a simple list of few rectangles for all the labels, not a circle, which would have been MUCH harder:
https://github.com/SimHacker/micropolis/blob/master/micropol...
So funny that you'd compare drawing circles in X11 -vs- PostScript. Have you actually tried to draw a circle with either API yourself -- let alone used the X11 SHAPE extension to make a round window? Here's an excerpt from the X-Windows Disaster which addresses that very topic -- specifically "in the case of arcs":
https://medium.com/@donhopkins/the-x-windows-disaster-128d39...
Myth: X is “Device Independent”
X is extremely device dependent because all X graphics are specified in pixel coordinates. graphics drawn on different resolution screens come out at different sizes, so you have to scale all the coordinates yourself if you want to draw at a certain size. Not all screens even have square pixels: unless you don’t mind rectangular squares and oval circles, you also have to adjust all coordinates according to the pixel aspect ratio.
A task as simple as filing and stroking shapes is quite complicated because of X’s bizarre pixel-oriented imaging rules. When you fill a 10x10 square with XFillRectangle, it fills the 100 pixels you expect. But you get extra “bonus pixels” when you pass the same arguments to XDrawRectangle, because it actually draws an 11x11 square, hanging out one pixel below and to the right!!! If you find this hard to believe, look it up in the X manual yourself: Volume 1, Section 6.1.4. The manual patronizingly explains how easy it is to add 1 to the x and y position of the filled rectangle, while subtracting 1 from the width and height to compensate, so it fits neatly inside the outline. Then it points out that “in the case of arcs, however, this is a much more difficult proposition (probably impossible in a portable fashion).” This means that portably filling and stroking an arbitrarily scaled arc without overlapping or leaving gaps is an intractable problem when using the X Window System. Think about that. You can’t even draw a proper rectangle with a thick outline, since the line width is specified in unscaled pixel units, so if your display has rectangular pixels, the vertical and horizontal lines will have different thicknesses even though you scaled the rectangle corner coordinates to compensate for the aspect ratio.
I created a new language called zis, which has a function named "doXeyes()". I can do xeyes in literally one line of code. It destroys postscript with it's amazing simplicity. Sorry for the snarkiness, but that's my point.
Nice way to completely miss Don's point. His point is that postscript provides all the necessary primitives to draw in 2D, consistently at every level of the stack. X-Windows is a continuation of the 'worse is better' NJ school of software design.
Snarkyness? What snarkyness? I don't understand what you mean. So I'd appreciate it if you'd explain what your point is more clearly, by directly addressing the questions I asked.
Please be kind enough to link to the source code of the language "zis" that you wrote, just like I linked to the source code that I and others wrote to illustrate my point. I'd like to see the actual code you wrote, so I don't miss your point, and can see that you're arguing in good faith. Thank you, kind sir or ma'am!
So what else is your language "zis" good for? Is it fully general purpose, easily editable at runtime, graphically skinnable with a build-in drawing editor, and dynamically scriptable and extensible by normal users, like HyperCard and HyperLook and Smalltalk? Do you think Alan Kay would describe "zis" as the "right way to go" like he described NeWS, and what other end-user problems does it solve, in the sense that he thinks HyperCard is brilliant and that Smalltalk pioneered? Is "zis" as "finished and smoothed and documented beautifully" as Alan Kay describes HyperCard?
Have you developed and shipped any commercial products or free software with your language, like SVR4 or SimCity, that I can see and run for myself, so I can be confident you're not just making stuff up or wildly exaggerating, and that it works as you advertise? And have you written any books or documentation or articles or research papers about it that I can read to learn more about it? Or at least a screen snapshot, please? What are the URLs?
Have you finished reading the X-Windows xeyes source code that I referred you to? Did you simply copy that code somebody else wrote into "zis" verbatim, or did you actually write your own original code? How is it licensed, and where has it been distributed: is it open source or not, and where's the repo?
Now that you have presumably used the X-Windows SHAPES extension API first hand yourself, please share your experience and tell me what you think of it: do you think that it is well designed and easy to use or not? What changes or improvements would you suggest? Did you run into any of its limitations, or notice any unnecessary complexity, or ICCCM window manager incompatibilities? How well does your language "zis" support the SHAPES extension and ICCCM protocol, or improve upon them, and what else is it good for than xeyes?
Finally, does "zis" support dragging and dropping eyes into each other, nesting their windows into an arbitrarily deep hierarchy, like my NeWS eyes did 27 years ago, and what ICCCM window managers support that feature, or did you have to write your own window manager or X extension to support that feature?
Thanks for taking all this time and effort to design and write and share all that code, and to support and clarify your fascinating arguments. I'm looking forward to seeing your code and your answers to my questions.
So, yes I've made xeyes in both X11/C and another language - it was part of a computer graphics course taken years ago, oddly enough, and it might have been PS, but I don't really remember. I did write one or two small programs in PS, I know that.
My point with the (imaginary) "zis" language is that comparing a domain-specific language like PS to C code is a strange comparison - not without merit, but PS is a higher level abstraction, which is great, but saying it is an amazing language because it is slightly easier than raw C is misleading. If I build up (or use) a nice library (and I'm not going to get pulled into defending X, I'm not as harsh as you on it, but it is ... painful ... to use - also, side note, I remember skimming through the Unix Haters Handbook when it came out, so I probably read your words back then, funny!) written in C, it is fair to compare that to PS.
I'd rather do it in OpenGL/C for instance, plus my version will be more performant. There's a reason that combination (or DirectX) is used in the vast majority of graphics software out there.
I truly enjoyed programming in PostScript. I actually like it better than Forth because it had some really nice constructs. If you did Forth programming and enjoyed the paradigm then PostScript is actually pretty good compared to JavaScript.