Re: Postscript questions



To add to the remarks already made by others posters :

It looks as if you believe the curly braces {} are defining a scope
(as in C, C++, Java etc...). Hence an outer procedure being
perceived as "global" and the inner one as "local".

This is *not* the way Postscript uses curly braces (or scopes).

Curly braces are behaving much more like the square brackets [],
the array "delimiters". The difference is deferred execution (and
the executable attribute), as already mentionned.
In Postscript, as in Lisp, data and program are more or less the
same. A procedure is an executable array. Executable arrays can be
nested, but that does not imply a local scope.

I would say the closest thing Postscript has to a C++ scope are
dictionnaries on the dictionnary stack, combined with the name
lookup rules. (Conceivably, the operand stack can also be another
distinct, mechanism to manage scope).

In other words, there is not much difference between :
[ [] ]
and
{ { } }

Both of those create an array.
Both of those arrays have a single element which is itself an empty
array.
Those lines differ in the way the interpreter executes (evaluate)
them. What's enclosed in a [] pair is evaluated immediately at
parsing time. What's enclosed in {} is evaluated later (possibly
never).
They also differ by the fact that the array created by {} have an
executable attribute set (and for that reason is commonly called a
'procedure')
You can mutate executable array into litteral one and back with the
'cvlit' and 'cvx' operators.

In other words :
[ [ ] cvx ] cvx
is indistinguishable from (yields the same operand stack as) :
{ { } }

Likewise :
{} cvlit
and
[]

While I am at comparing languages, I may as well mention that code
like:
MyProc
does not merely operate like a function call (as one would expect
coming from C / C++ background). It is closer to Lisp evaluation :

Such a line leaves an executable name on the operand stack and the
interpreter attempts to evaluate it.
Evaluating an executable name means that the interpreter searchs
the name through the dictionnary stack and when found, evaluate the
value associated with the name.
What happens next depends on both the type and the executable
attribute of the value.
If the value is an executable name, it's looked up and evaluated as
described above.
If the value is an executable array (a procedure if you prefer),
each element of the array is evaluated in the order of the array.
If the value is anything else, it's placed on the operand stack.

In a nutshell :
{} are array delimiter, with execution (evaluation) deferred until
after parsing time. Unlike other languages, {} don't define a
scope.

_______________________________________________________
François Robert
(to mail me, reverse character order in reply address)
.