From willett!dwp Fri Mar 2 02:04:05 1990 Date: Tue, 27 Feb 90 08:00:08 EDT From: willett!dwp (Doug Philips) Subject: Here it is, just in case you need it To: don@brillig.umd.edu Date: Sun, 25 Feb 90 14:26:42 -0500 From: uunet!cs.UMD.EDU!mimsy!don (Don Hopkins) Message-Id: <9002251926.AA06898@brillig.UMD.EDU> To: willett!dwp Subject: Re: Why is Postscript not Forth? Newsgroups: comp.lang.forth In-Reply-To: <528.UUL1.3#5129@willett.UUCP> References: <9002210136.AA20515@jade.berkeley.edu> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Cc: In article <528.UUL1.3#5129@willett.UUCP> you write: >> PostScript already provides words to convert between types, but some >> pairs of types are not mutually convertible. The original point was >> that Forth is inherently untyped and PostScript is inherently strongly >> typed, and that this difference is fundamental. The above argument >> supports that claim. In Forth, you can ultimately do anything you want >> with a stack cell, and in PostScript, you can only do "type consistent" >> things. >It doesn't really matter if you can't go immediately from one type to >another. All that matters is that some sequence of type converting words >can get you from one place to all the other places. If the type system >has disjoint partitions, then this is true and I'll concede the point. If >there are no disjoint partitions then it is merely a matter of convenience >(i.e. having to write your own foo->bar word that does the twelve necessary >intermediate type perturbations). > PostScript objects have their type stored with them (be they on the stack, in arrays, in dictionaries, or anywhere else in memory). Forth objects do not. A cell is a cell is a cell, no matter what you think of it. Your program cannot tell what you were thinking. You have to remember what type is stored where, and call the appropriate function for that type, and forth programs have to assume that they are called with arguments of the correct type. You can't write a forth word that does one thing if passed an integer, or another thing if passed a string, because there is no way it can tell by looking at the the stack. You have to have two different forth words, one for integers and one for strings, and the programmer has to call the appropriate one at the appropriate time. PostScript programs can behave differently according to their type of arguments. A good example is the ShowThing function in NeWS. It takes as an argument a Thing. A Thing can be any of several different data types. If it's a string, ShowThing renders the string in the current font. If it's a dictionary, it sends a /paint message to it. If it's the name of an icon, it paints that icon. If it's an array, it breaks it up and deals with each element individually: a font sets the current font, a color sets the current color, a pair of numbers offsets the current point, and it can also contain any of the above types. Pointy head academic types call this "polymorphism". Each element of an array can contain any type of object. The objects are tagged with their type, not the places where the objects are stored. PostScript code is simply an executable array of PostScript objects. "Decompiling" PostScript code is trivial because of the type information stored with each element. There is really no PostScript compiler. Just a scanner that translates text to typed objects. You can extend the language by creating new control structures, etc, (like "case") by defining new functions, not by changing the syntax of the language or the format of code stored in memory; any extensions you make to PostScript (in the sense of defining new functions -- I don't mean hacking the source code to the interpreter itsself) do not necessitate changes to the PostScript "decompiler". I surround "decompiler" in double quotes because "==", the operator which prints a PostScript object, is as much of a decompiler as most people need, and you could write a nice indenting decompiler in terms of "==", "print", and a little recursion. Decompiling Forth is not trivial, because the decompiler has to know about any in-line literals or other tricky things that might be embeded in the code (like "literal", '(.")', "(;code)", "?branch", "exit", and the "{{" and "}}" closures that have been mentioned). Any extensions you make to the language that allot memory in the middle of code, you have to teach the decompiler about. The Forth compiler and scanner is written in Forth. There is no PostScript compiler, but the scanner is not written in PostScript (every implementation I have seen was in C). PostScript is not threaded. The PostScript interpreter "executes" PostScript data structures, by looking at their type information, and then deciding what to do (usually with a big switch statement). The Forth inner interpreter, "next", is *much* simpler than any PostScript interpreter -- one instruction on some machines. -Don --- Preferred: willett!dwp@gateway.sei.cmu.edu OR ...!sei!willett!dwp Daily: ...!{uunet,nfsun}!willett!dwp [in a pinch: dwp@vega.fac.cs.cmu.edu]