From: anton@mips.complang.tuwien.ac.at (Anton Martin Ertl)
Subject: Re: locals (was: Floating Point)
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Date: Thu, 15 Oct 1992 14:11:24 GMT

In article <1992Oct5.165349.16826@Informatik.TU-Muenchen.DE>,
pazsan@Informatik.TU-Muenchen.DE (Bernd Paysan) writes:
|> 
|> In article <1992Sep28.070230.13446@email.tuwien.ac.at>,
anton@mips.complang.tuwien.ac.at (Anton Martin Ertl) writes:
|> |> I have spotted one problem with locals: They cannot be postponed, and
|> |> they are incompatible with the current model of postponing (dictionary
|> 								^^^^^^^^^
|> |> lookup at postpone time). This may look like a purists complaint, but
|>    ^^^^^^^^^^^^^^^^^^^^^^^^
|> |> such incompatibilities tend to cause problems when you want them
|> |> least.
|> |> 
|> It should be: "dictionary lookup at postpone's execution time"; and since
|> POSTPONE must be immediate, this is the compile time.

This is the compile time of the word containing the POSTPONE. But with
respect to the postponed word, it's compile-compile time, which I
chose to call postpone time. I.e. at postpone time the word is
postponed; when the word containing the postpone is executed, the word
is compiled (compile-time); and finally the word may be executed
(run-time).

|> Another question: Where do
|> you want locals POSTPONEd to (say compiled instead of postponed, it is the right
|> word)? A local is local to the definition where it appears (thus it is called
|> "local"). It doesn't exist in other definitions. Compiling or postponing is
|> adding code to other definitions. Example:
|> 
|> : LOCALCOMPILER  ( anything -- )  LOCAL A
|>   POSTPONE A ; IMMEDIATE
|> 
|> : LOCALUSER ( a b -- ) { A B -- } \ another local syntax
|>   LOCALCOMPILER B + ;
|> 
|> What do you expect LOCALUSER will do? :-)

Well, I expect POSTPONE to complain or LOCALCOMPILER or LOCALUSER to
crash or behave unpredictably. That's what I mean with "the concepts
are incompatible": I can think of no way to combine locals and
POSTPONE.

Let me explain one application I am thinking of:

Gray (a parser generator written in Forth) has rules of the form:

(( factor (( "*" factor {{ * }}
          || "/" factor {{ / }}
          )) **
)) <- term ( -- n )

where the things in curly brackets are actions written in Forth.
Currently Gray works as follows: "((", "{{", "**", etc are Forth words
that build a data structure. "{{" builds an anonymous word (with
":NONAME"), and "}}" terminates this, similar to ";". Later, Gray
builds an executable parser as collection of Forth words; The
anonymous words are "COMPILE,"d into the parser.

Now it would be nice to extend Gray with variables local to the
*rule*. This can be done by remembering the code between curly
brackets as *string*; later (at parser generation time) the strings
are "EVALUATE"d in compile mode. There's one problem with this: The
"EVALUATE" will happen in a different environment (dictionary
contents, search order) than the old scheme, so code may break, if I
make this change. Apart from that, it bugs me that I cannot use the
skalpels that are especially designed for such jobs ("COMPILE," or
POSTPONE), but have to use a butcher's knife like "EVALUATE".

Why do I feel that way about "EVALUATE": "EVALUATE" uses the
dictionary ("POSTPONE" does not need it at compile time). What it
does, depends on a lot of things that are hard or impossible to
control: The search order and the words defined in the dictionary
(among them redefined words). Under some circumstances I can control
this; in these cases "EVALUTE" is ok. But if I use it in a word
accessible to others (e.g. in the parser generator, or in a library),
this word inherits "EVALUATE"s problems and I have to warn the users
about it. Eventually this will cause a lot of pollution of the Forth
environment. So: "EVALUATE" is incompatible with modular programming.

|> |> Apart from that, locals look fine (but not the Basis 15 locals
|> |> wordset). But who knows what other evils they hide behind their back?-)
|> |> 
|> We have LOCAL| last to first | now, that takes ( first to last -- ).
|> And you can
|> define anything like TILE's syntax with (LOCAL).

I meant the restrictions on LOCALs usage.

I did not know about the "last to first" syntax, but I find it
horrible. One of the few things where the opinions of the Forth
community don't differ is stack comments. Now what's more natural than
to write locals in the same order? All the locals schemes I know
(Tevets, Glass' and Patels (TILE)) use this order.

Writing it the other way round is error-prone and harder to read. I
guess the rationale for this is that it saves the vendors half an hour
in the implementation. But it will cost its users much more. Yes, I
know I can do something different with (LOCAL), but I may have to read
other peoples code and I really would prefer a standard that I can
use.

Hmm, looking into BASIS 15, section B.17, I see two examples of doing
it the "last to first" way and none doing it the right (8-) way. A
proposal to the ANSI TC: I will try to implement a right way locals
syntax (with "(LOCAL)"), if you promise me to put it in that section.

- anton
-- 
M. Anton Ertl                    Some things have to be seen to be believed
anton@mips.complang.tuwien.ac.at Most things have to be believed to be seen