Re: [SPOILER] Re: Perl Quiz of the Week #25 (RPN calculator)

Mark Jason Dominus <[email protected]> Tue, 5 Oct 2004 13:01:28 -0400
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
On Oct 5, 2004, at 12:42 PM, Peter Haworth wrote:
>
> I'm thinking about allowing user-defined functions, but not being a
> Forth programmer, I'm not sure how the syntax ought to look.

My dim recollection from Forth is that it looks something like this:

	'function-name' : op op op op op op ;

Where ':' and ';' are special operators.  ':' pushes a special mark 
value onto the stack, and
also enables a quoting mode that disables ordinary evaluation.  The 
following operators are
pushed onto the stack atop the mark.  The ';' operator tells Forth to 
pop the operators until it
sees the special mark; this becomes the definition of the function, and 
the ';' pops the function name off
the stack and associates the name and the definition in a global 
dictionary.

Afterwards, evaluating 'function-name' is simple: just expand the 
definition and process it as usual.

I believe PostScript is similar.  Come to think of it, I have the 
PostScript language reference on my desk here...
Aha, yes.  I may not have described Forth accurately, but my 
description is very close to what PostScript does:

> Scanning the program fragment
>
> 		{add 2 div}
>
> produces a single procedure object that contains the name object add, 
> the integer object 2, and the name object div. When the scanner 
> encounters the initial {, it continues scanning and creating objects, 
> but the interpreter does not execute them. When the scanner encounters 
> the matching }, it puts all the objects created since the initial { 
> into a new executable array (procedure) object.
>
> The interpreter does not execute a procedure immediately, but treats 
> it as data; it pushes the procedure on the operand stack. Only when 
> the procedure is explicitly invoked (by means yet to be described) 
> will it be executed. Execution of the procedure—and of all objects 
> within the procedure, including any embedded procedures—has been 
> deferred. The matter of immediate versus deferred execution is 
> discussed in Section 3.5, “Execution.”

In PostScript you define a procedure by doing something like:

	{ 2 mul } /double def

After processing the '}' operator, the stack contains an anonymous 
function.  '/double' pushes the "name object" representing the name 
"double", and then "def" is a binary operator which expects a name and 
a value and associates the two in the current dictionary.

I don't think I have mentioned this month that PostScript is a 
fabulously elegant and powerful language, and that the language 
reference manual is clear and well-written.