[comp.lang.postscript] Beyond PostScript

don@brillig.umd.edu (Don Hopkins) (04/19/89)

What if there was another bit in every PostScript array reference
(like the executable bit), that when set, makes it an "inline
executable array", i.e. when the interpreter hits an inline executable
array, it would execute it (push it directly onto the execution stack)
instead of pushing it onto the operand stack. Then autobind could
replace names that were bound to inline executable arrays, as well as
built-in operators like it does now... So you could define your own
autobound inline PostScript functions, which didn't have to be looked
up on the dict stack at run time! (You could accomplish the same thing
manually by pushing the array and then doing an exec, ala {//myfunc
exec}, but that's twice as many runs through the interpreter loop.)
Inline executable arrays could save a lot of dictionary searches,
especially when used for the non-primative functions in systemdict
(the last dict in the search list, and quite a whopper), and commonly
called functions in userdict.

That's the funny thing about PostScript ... The interpreter treats
arrays differently than everything else: When it comes across an
executable array in a function, it pushes the array onto the operand
stack, same as with literal arrays.  I think it could speed things up
a bit if you could have a kind of super-executable array that was
automatically executed, that the scanner automatically autobinds into
your functions.

Something Forth has that PostScript doesn't is the notion of
"immediacy". (This is something different than "inline executable
arrays" described above.) Each Forth word has a bit that tells if it's
immediate or not (most aren't). The compiler (i.e. scanner, in the
case of a hypothetically extended PostScript) *executes* an immediate
word (function) instead of compiling it (i.e. putting it into an
executable array). It would be like an extended mode of autobind.
Immediate functions take care of compiling (or scanning) themselves.
They can even read things off the input stream following the token
that invoked them.  This mechanism is used in Forth for implementing
control structures, macros, inline string literals, and other types of
magic compiler constructs.  The way the NeWS scanner works would have
to be changed to accomodate immediate PostScript function, because the
scanner uses its own special stack for building executable arrays.
You'd want the PostScript scanner to put a mark on the operand stack,
and push each array element as it's scanned. When it scans an
executable token that's bound to an immediate function on the dict
stack, it would execute that function, then go on scanning the rest
of the array.  Immediate PostScript functions would be able to look at
the operand stack to see what of the array has been scanned so far,
and anything they left on the stack would end up in the array.

User definable magic variables and tuple-space operations (ala PIX)
could be a great deal of fun, too! [Check out Wm Leler's "PIX, the
latest NeWS" in the Proceedings of COMPCON Spring '89, IEEE, and N.
Carriero and D. Gelernter's "Linda In Context", in the April 1989
CACM.]
 
But then it wouldn't be PostScript TM, would it?  (Ah, yes, the
eternal tension between featurization and standardization. Phooey.
Onward!)

	-Don

fons@cs.vu.nl (Fons Botman) (04/20/89)

In article <16993@mimsy.UUCP> don@brillig.umd.edu.UUCP (Don Hopkins) writes:
>What if there was another bit in every PostScript array reference
>(like the executable bit), that when set, makes it an "inline
>executable array", i.e.
 [example, description and advantages deleted]

I think something like that could be useful, but could not that be done by
redefining "def"?  Something like:

/olddef /def load def
/def { superbind olddef } olddef

/superbind { % proc -> newproc 
    integrate-operators			% What autobind usually does
    integrate-executables		% What you like to do
} def

Both the intergrate functions recursively walk down the executable arrays and
perform the substitutions.

intergrate-executable does something like:

/double { 2 mul } def

{ xcoord ycoord double moveto } intergrate-executable
==>
{ xcoord ycoord 2 mul moveto }

Is this the kind of thing you had in mind?
With some extra work you can also do constant folding etc.



>That's the funny thing about PostScript ... The interpreter treats
>arrays differently than everything else: When it comes across an
>executable array in a function, it pushes the array onto the operand
>stack, same as with literal arrays.  

It does so also with executable number and strings.  The only exception is an
executable name which is looked up and executed.


>Something Forth has that PostScript doesn't is the notion of
>"immediacy". (This is something different than "inline executable
>arrays" described above.) Each Forth word has a bit that tells if it's
>immediate or not (most aren't). The compiler (i.e. scanner, in the
>case of a hypothetically extended PostScript) *executes* an immediate
>word (function) instead of compiling it (i.e. putting it into an
>executable array). It would be like an extended mode of autobind.
>Immediate functions take care of compiling (or scanning) themselves.
>They can even read things off the input stream following the token
>that invoked them.  This mechanism is used in Forth for implementing
>control structures, macros, inline string literals, and other types of
>magic compiler constructs.  The way the NeWS scanner works would have
>to be changed to accomodate immediate PostScript function, because the
>scanner uses its own special stack for building executable arrays.
>You'd want the PostScript scanner to put a mark on the operand stack,
>and push each array element as it's scanned. When it scans an
>executable token that's bound to an immediate function on the dict
>stack, it would execute that function, then go on scanning the rest
>of the array.  Immediate PostScript functions would be able to look at
>the operand stack to see what of the array has been scanned so far,
>and anything they left on the stack would end up in the array.

I must admit that this is one of the the things in Forth i didn't like
completely, but you can easily define your own control structures in
postscript, "case" is one of the standard examples.

something {
 1 { (one) show }
 2 { (two) show }
 { (many) show }
} case


> From: chris@goedel.uucp (Chris White)
> Subject: Re: Beyond PostScript
> Keywords: PostScript, Forth, Scheme
> 
> This seems like a useful feature. It makes it easier
> to construct executable arrays that must have "live"
> information stuck in them during creation time. (The
> old way is to use "[....] cvx" where everything inside
> the square brackets often becomes unreadable due to
> the fighting you have to do to keep the evaluator from
> executing things too soon)
> ...
> I think scheme (lisp dialect) has a variation on this.
> 
> Anyway, you still have to come up with a reasonable
> syntax for the special array.
> 
> How about:  < {1 2 add} iexec 3 add >
> 
> When scanned, this would push {3 3 add} onto the operand
> stack. Does either PostScript or NeWS use the <> combination for
> some kind of system construct?

Alas, <A8B9> is a hexadecimal notation for a string.

Scheme has indeed such a construct:
`(a ,(+ 3 4) c)
yields
(a 7 c)

Defining an operator "parse-it" which does:

{ a {, 3 4 add } c } parse-it
==>
{ a 7 c }

should be no problem. Then you can write for instance.

/movethere { {, 10 3.14 mul} {, 5 3.14 mul} moveto } parse-it def

Or you could make superbind do this also.


I am off to an appointment now, so i can't generate the source, but mail me if
you have problems.


					The Fons

paul@moncam.co.uk (Paul Hudson) (04/21/89)

In article <1458@cmx.npac.syr.edu>, chris@goedel.uucp (Chris White) writes:

> stack. Does either PostScript or NeWS use the <> combination for
> some kind of system construct?
> 
>         -- Chris


Yep. Means string with each byte as a pair of hex digits. 
The addition of linve arrays seem of dubious benefit. There are a lot
of things that ought to be fixed in PostScript before worrying about minor
twiddles like this.
Paul Hudson 

Snail mail: Monotype ADG	Email:	...!ukc!acorn!moncam!paul
	    Science Park,		paul@moncam.co.uk
	    Milton Road,	"Sun Microsysytems:
	    Cambridge,		 The Company is Arrogant (TM)"
	    CB4 4FQ