Article: 16092 of comp.lang.forth Path: news.tuwien.ac.at!mips.complang.tuwien.ac.at!anton From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Newsgroups: comp.lang.forth Subject: Re: Don't postpone, evaluate. Date: 5 May 1995 17:16:25 GMT Organization: Institut fuer Computersprachen, Technische Universitaet Wien Lines: 98 Distribution: world Message-ID: <3odmha$i3t@news.tuwien.ac.at> References: NNTP-Posting-Host: mips.complang.tuwien.ac.at In article , wilbaden@netcom.com (W.Baden) writes: |> In the current FD I hint at but otherwise neglect the suggestion that |> POSTPONE can be replaced by EVALUATE. |> |> How about it? No! Don't use EVALUATE where POSTPONE will do! I posted an article to this effect some time ago. As Jonah Thomas pointed out, the late binding will give you (and, more probably, an unsuspecting user of your code) big headaches: Maybe the user creates a word with a name you use in your delayed code, or she changes the search order. In both cases your code will break while a version using POSTPONE will work. I also asked about uses of EVALUATE that could not be replaced with POSTPONE and friends and did not get many answers. |> Using only the Core wordset and nothing from the Core Extension wordset |> or any other wordset how would you define AGAIN using POSTPONE? |> |> With EVALUATE it's easy. |> |> : AGAIN S" 0 UNTIL" EVALUATE ; IMMEDIATE How about : again 0 postpone literal postpone until ; immediate Looking around, I found my old posting: Article: 11414 of comp.lang.forth Path: news.tuwien.ac.at!mips.complang.tuwien.ac.at!anton From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Newsgroups: comp.lang.forth Subject: EVALUATE considered dangerous (Was: redirection of input) Date: 25 Aug 1994 17:20:39 GMT Organization: Institut fuer Computersprachen, Technische Universitaet Wien Lines: 51 Distribution: world Message-ID: <33ijt7$doo@news.tuwien.ac.at> References: <3394sn$psg@marsupial.jpl.nasa.gov> NNTP-Posting-Host: mips.complang.tuwien.ac.at EVALUATE may be a useful word for some purposes, but it is a dangerous kludge in others. Here is an example of an application of the "dangerous kludge" type: In article <3394sn$psg@marsupial.jpl.nasa.gov>, lgc@robotics.jpl.nasa.gov (Loring Craymer) writes: |> In memory redirection is |> accomplished through EVALUATE; to process a string through the input |> stream, it may be necessary to prefix the string with a phrase which |> processes the rest of the input stream (as in taking "PROCESSOR ", |> appending "", and then calling EVALUATE to process |> the resulting string). It should be clear why this is a kludge: Instead of directly redirecting the input stream and then calling the processor you have to construct a new string (with all the ensuing memory management troubles) and then EVALUATE it. EVALUATE will execute the processor, and hopefully that will consume the whole string (if it does not, you are in trouble). Now, why is it dangerous? Because in the tests this usually will work fine, just as you wanted. But later, in action, what happens if the user changes the search order so "PROCESSOR" is not found? Or worse, if another word called "PROCESSOR" is found? The user gets a nasty surprise and you get a bug report. The problem is that such uses of EVALUATE rely on too much state: On the search order and on the states of the word lists in the search order. What can be done about this problem? The best solution is to avoid such uses of EVALUATE. Unfortunately, if you want to write ANS Forth conforming programs, this is often not possible (the TC seems to have been satisfied by such dangerous kludge solutions instead of adding words to avoid them). So, you will have to live with EVALUATE, but you can make it safer: put your PROCESSOR in a separate wordlist, that the user has no access to (at least not normally); before calling EVALUATE, make that wordlist the first one in the search order. Afterwards (or in PROCESSOR) the original search order has to be restored. This is more kludgy, but less dangerous than the originl approach. I wonder what applications apart from such kludges there are for EVALUATE. I can think of two: Emulating the execution behaviour of Postscript (which normally behaves as if every word was wrapped in a layer of EVALUATE) and for interpreting user input. Any other applications? - 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 http://www.complang.tuwien.ac.at/anton/home.html Article: 16183 of comp.lang.forth Path: news.tuwien.ac.at!mips.complang.tuwien.ac.at!anton From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Newsgroups: comp.lang.forth Subject: Re: Don't postpone, evaluate. Date: 8 May 1995 16:15:26 GMT Organization: Institut fuer Computersprachen, Technische Universitaet Wien Lines: 56 Distribution: world Message-ID: <3olg2u$9rr@news.tuwien.ac.at> References: <3odmha$i3t@news.tuwien.ac.at> NNTP-Posting-Host: mips.complang.tuwien.ac.at In article , wilbaden@netcom.com (W.Baden) writes: |> > >: AGAIN S" 0 UNTIL" EVALUATE ; IMMEDIATE |> > |> > I did it without EVALUATE because I wanted code that would run in |> > cooperation with a lot of other people's code. If they happen to |> > make a word with the same name as one I EVALUATE they could get a bug |> > that's very tricky to track down. It could be done safely with |> > EVALUATE by setting the search order just so first -- which requires |> > search-order words. |> |> Better think again. So his user writes: : UNTIL ." Hello, Wil, I'm a bug" ; immediate : test begin ." let's see" cr again ; After compiling the second line of test he sees Hello, Wil, I'm a bug And at the ; the user gets a message about the word being unstructured. Now don't tell me that the user has no business defining UNTIL. First of all this is Forth, not Ada's school for politically correct programmers. Second, there are completely legitimate reasons for defining standard words, e.g., in an application wor list for users that do not come into contact with the more down-to-earth facts of Forth (like UNTIL). |> However, the following are all completely equivalent. |> |> : foo PLEASE " mumble " ; IMMEDIATE |> |> : foo S" mumble " EVALUATE ; IMMEDIATE |> |> : foo ]] mumble [[ ; IMMEDIATE The first two may be equivalent, the third isn't. Consider: : mumble ... ; : bar foo ; |> A string will be compiled as it is evaluated ,and changing definitions |> of words in the string will not affect what has already been compiled. No, but it will affect what is only present in string form. - 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 http://www.complang.tuwien.ac.at/anton/home.html Article: 16241 of comp.lang.forth Path: news.tuwien.ac.at!mips.complang.tuwien.ac.at!anton From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Newsgroups: comp.lang.forth Subject: Re: Don't postpone, evaluate. (Should be: Don't EVALUATE when you can POSTPONE) Date: 9 May 1995 17:57:03 GMT Organization: Institut fuer Computersprachen, Technische Universitaet Wien Lines: 61 Distribution: world Message-ID: <3ooadf$hek@news.tuwien.ac.at> References: <3odmha$i3t@news.tuwien.ac.at> <3oko8r$gpk@minnie.informatik.uni-kiel.de> NNTP-Posting-Host: mips.complang.tuwien.ac.at In article , wilbaden@netcom.com (W.Baden), who should get a newsreader with proper attribution, writes: |> : UNLESS S" 0= UNTIL" EVALUATE ; IMMEDIATE |> |> : NOTIF POSTPONE 0= POSTPONE UNTIL ; IMMEDIATE ... |> It is true that if you want to re-define 0= or IF then you must also |> re-define NOTIF, whilst UNLESS will adjust. It depends on what you want. In Forth the redefinition of one word usually does not change the behaviour of others. So Forth users are not used to this kind of "adjustment". Those who want adjustment use Postscript. Also, your "adjustment" is quite fragmentary. Only those words that compile UNLESS after the change of, say, 0=, adjust. Why not remove the IMMEDIATE (ok, does not work with UNTIL, but you get the idea) and make the adjustments more pervasive. Still, this does not adjust other uses of 0=. We have traditionally used other means for changing the behaviour of existing words and words that use them: e.g., deferred words and (dare I meantion it?) patching the intermediate code. IMO these tools (even patching) are better suited for this purpose: Fewer hidden gotchas, more efficient. All right, if you want to use "adjusting" programs, go ahead. But if you distribute them, please put a warning on them about all words that might adjust to the (re)definitions of other words. Finally, here's another way to break UNLESS: wordlist constant myvoc myvoc set-current : unless2 postpone unless ; immediate : ; POSTPONE ; ; : : ... : begin ... myvoc 1 set-context : xxx begin 0 unless2 ; will give you something like Error: Undefined word Doing the same with NOTIF would work. - 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 http://www.complang.tuwien.ac.at/anton/home.html