[comp.lang.postscript] Bind is a travesty

rokicki@neon.Stanford.EDU (Tomas G. Rokicki) (04/29/91)

I have often expressed the opinion that `bind' was the greatest disservice
to the computing community Adobe has ever made.  The attached file will
illustrate why.

Use this file to test random prologs from various applications.  The
prologs should be `clean'---they should leave all stacks like they were
originally (no save at the beginning), and they should not exitserver.
Most prologs can easily be modified to fit these requirements.  Insert
the prolog at the end of this PostScript file, and add `bind-summary'
to the very end.  Print.

*Any* free variables caught point out a potential problem; too many
outer definitions show another possible problem.

[I must admit that I myself am far from perfect; my dvips prolog, even
after many hours spent making sure that bind was used correctly, still
fails this test for a few variables.  That is being fixed immediately.
But this is just more evidence that bind was a serious mistake.]

My diatribe against bind is available upon request.

%! This PostScript file Copyright 1991 by Radical Eye Software.
%                       All Rights Reserved.
%
%   This little file will help you test your PostScript prolog for bind
%   problems.  A bind problem is a case where the `bind' function is used
%   on `free' variables:
%
%      /test { x y add } bind def
%
%   may not work correctly if the document is included in an environment
%   where `x' is defined on the dictionary stack.
%
%   To use this file, just append the prolog you wish to test to this file,
%   and add a call to `bind-summary' at the very end of the prolog.  That
%   should print out a page containing a list of `free' variables that were
%   bound (all of which probably point out problems in your prolog) and a
%   list of symbols defined in the dictionary on the outermost level.
%   If there are more than a few of these latter, then you are assuming
%   that the default dictionary is a certain size, which is not a good idea.
%
%   If you don't know what you are doing, don't ever use bind.  This file
%   should convince you of that when you run it over typical prologs.
%
%   Generally, the prolog is the part from the beginning of the file to
%   the %%EndProlog comment.
%
%   This file needs to be made much more robust.
%
%   This won't work for `exitserver' type prologs, but that should be easy
%   to fix.
%
%   This works by redefining `bind'.
%
/real-bind /bind load def
%
/badbinddict 200 dict def
%
/outerbinddict 200 dict def
%
/userdict outerbinddict def
%
/rbind {
   dup type dup /arraytype eq exch /packedarraytype eq or
   {
      dup rcheck { { rbind } forall } { pop } ifelse
   }
   {
      dup type /nametype eq {
         dup xcheck {
            dup where { pop pop } {
               badbinddict begin
                  (Uh oh, possible problem?) def
               end
            } ifelse
         } { pop } ifelse
      } { pop } ifelse
   } ifelse
} def
%
/bind {
   dup rbind
} def
%
%   Report what happened.
%
/bind-summary {
   grestore      % just in case someone did something smart.
   end           % kill off the outerbinddict
   /y 720 def
   /normalfont /Times-Roman findfont 10 scalefont def
   /bindwriteln {
      72 y moveto normalfont setfont show
      /y y 10 sub def y 72 lt {
         showpage /y 720 def
      } if
   } def
   /tempstring 100 string def
   (Bind test results) bindwriteln ( ) bindwriteln
   (Free variables caught) bindwriteln ( ) bindwriteln
   badbinddict { pop tempstring cvs bindwriteln } forall
   ( ) bindwriteln
   (Outer definitions made) bindwriteln ( ) bindwriteln
   outerbinddict { pop tempstring cvs bindwriteln } forall
   ( ) bindwriteln
   showpage
} def
%
%   We start outerbinddict, so the prolog puts its definitions there.
%
outerbinddict begin gsave
%
%   Put your prolog here.  At the end, after the prolog, add a call to
%
%   bind-summary

glenn@heaven.woodside.ca.us (Glenn Reid) (05/05/91)

Tomas G. Rokicki writes

> I have often expressed the opinion that `bind' was the greatest disservice
> to the computing community Adobe has ever made.  The attached file will
> illustrate why.
>
> *Any* free variables caught point out a potential problem; too many
> outer definitions show another possible problem.

With great respect, Tom, I have no idea what you're getting at.  Please
explain what is wrong with "bind".

Is it just that you can't redefine a name after the fact?

> My diatribe against bind is available upon request.

Rather than posting the entire diatribe, try to summarize what is wrong
with it for us curious types.  I've never seen it cause any particular
trouble.

> %   A bind problem is a case where the `bind' function is used
> %   on `free' variables:
> %
> %      /test { x y add } bind def
> %
> %   may not work correctly if the document is included in an environment
> %   where `x' is defined on the dictionary stack.

If `x' is defined but is not an operator, "bind" leaves it alone, as it
should.  In your example, only "add" would be affected by the "bind"
operation, unless for some reason "x" or "y" was a name that pointed
directly to an operator object.  What exactly is the problem?

Also, what brand of PS interpreter are you using, just to calibrate?

Curiously,
Glenn

--
 Glenn Reid				RightBrain Software
 glenn@heaven.woodside.ca.us		NeXT/PostScript developers
 ..{adobe,next}!heaven!glenn		415-326-2974 (NeXTfax 326-2977)

rossc@extro.ucc.su.OZ.AU (Ross Cartlidge) (05/14/91)

glenn@heaven.woodside.ca.us (Glenn Reid) writes:
...
>> %   A bind problem is a case where the `bind' function is used
>> %   on `free' variables:
>> %
>> %      /test { x y add } bind def
>> %
>> %   may not work correctly if the document is included in an environment
>> %   where `x' is defined on the dictionary stack.

>If `x' is defined but is not an operator, "bind" leaves it alone, as it
>should.  In your example, only "add" would be affected by the "bind"
>operation, unless for some reason "x" or "y" was a name that pointed
>directly to an operator object.  What exactly is the problem?
	
	In my experience the "bind" problem is part of a larger
	problem in PostScript. It is the slightly different
	behaviour of Operators and Procedures.

	A few years ago I wrote a PostScript prolog called "multi.ps"
	which when prepended to ANY PostScript (not just EPSF) it
	put multiple pages on a page. It worked by overloading
	all the operators which affect the absolute graphics (like showpage
	and initgraphics, etc). My biggest problem was that it meant
	changing many operators into procedures. This broke arbitrary
	PostScript in (at least two) ways.

	1. bind used to break recusion.
	   EG
		/showpage { showpage (G'day) == } bind def
	   now generated an infinite loop

	2. procedures don't execute when pushed onto stack
	   EG
		/showpage { //showpage (G'day) == } def
	   will now push "showpage" onto the stack but not execute it.

	I realise the PostScript which causes the problem is a bit
	naughty, but lots of PostScript translators (TeX for one)
	do things like this. As for Apple's Laserprep - it does every 
	naughty thing in the book.

	But the problem remains that to fix 1. I have to
	overload bind with a rather messy function and
	I have no way of fixing 2. as // is a lexical operator-
	and ofcourse // is not the only way "operators" can be
	pushed onto the stack.

	If anyone has a solution to this I'll put it into
	multi.ps straight away.
-- 
________________________________________________________________________
Ross Rodney Cartlidge			    |   rossc@extro.ucc.su.oz.au
University Computing Service, H08	    |   Phone:     +61 2 6923497
University of Sydney, NSW 2006, Australia   |   FAX:       +61 2 6606557