ir230@sdcc6.ucsd.edu (john wavrik) (07/15/90)
IN DEFENSE OF FORTH-83 It would be illuminating if some of the members of the FORTH-83 team presented the rationale for their decisions. I was not a member of that team, but I have had numerous discussions with its chairman, Guy Kelly, about the 83 Standards. Disclaimer: The following views are my own. They are based on impressions gained from conversations together with my own experiences with Forth before and after Forth-83. While I do not agree with everything the 83 team did, I also don't think their work was entirely as haphazard and incompetent as it is currently being portrayed. Here is a summary of the two existing Forth standardization efforts: The Forth-79 team saw its work as an effort to turn fig-Forth into a Standard. Forth-79 is essentially fig-Forth with only a few modifications [and, unfortunately, omissions]. The Forth-83 team saw its work as an effort to produce a final "touch up" of Forth. To deal with some inconsistencies and fix the actions of a few words. The Forth-83 changes that are freshest in mind are those which caused changes in code and those which are subjects of current controversy. This essay will deal with these. LOGIC AND BITWISE OPERATIONS The words AND, OR and NOT are part of the English language. They are used in common speech in a logical sense. If it is NOT raining then we will go to the zoo. we do not say If raining = 0 then we will go to the zoo. The function of NOT is to change truth value. It is the proper word to use for logical statements. 0= is not the proper word here for two reasons (1) Semantically we are reversing truth value, not testing a number for zero; (2) The fact that 0= may change truth value is an accident of a particular representation for booleans. [In many Forth systems the word WHILE is an alias for IF -- but we do not and should not use them interchangeably.] Around the turn of the century, the English mathematician George Boole invented the idea of using numerical representation for logical concepts. He found that if TRUE is represented by the number 1 and FALSE by 0, statements in logic could be turned into arithmetic statements. He developed an algebra of logic. In the early days of computer circuitry this proved to be the key to having machines perform logical operations. The names AND, OR and NOT for bits come from this Boolean transformation of logic to numbers. Eventually the words AND, OR, etc. came to be used for operations on bit patterns rather than individual bits. The words acquired a second meaning. In Forth-79, TRUE was represented by 1 and FALSE by 0. The words AND and OR had bitwise meanings but they also worked correctly for booleans. NOT, on the other hand, was a synonym for 0= and could only be used in the logical sense. It seemed inconsistent, when using bit masks, to have AND, OR, XOR function as in assembly language -- but to have no equivalent of NOT (the word COM for bitwise complement was only in the Reference Word Set). The Forth-83 team discovered that if TRUE were represented by the number with all bits set (rather than by 1) then the bitwise NOT would also be the logical NOT. We had, in fact, been using the wrong number to represent truth value. Once the change is made, everything falls into place and the logical/bitwise discrepancy disappears. [The current discussion of the issue by the ANSI team is bizarre. Mitch Bradley informs us that everyone agrees to represent TRUE by all bits set. Once this is agreed on, there is no reason not to use NOT. What caused many of us grief in switching from '79 to '83 is that we did arithmetic on flags. It is poor programming practice to confuse numbers and booleans (which includes confusing NOT with 0=). Strongly typed languages enforce the distinction. Forth relies on the discipline of the programmer.] MONO-ADDRESSING Forth-79 had inconsistencies in operations using addresses. The word ' (tic) was state-smart and left the parameter field address. the word FIND, on the other hand, was not state-smart and left the code field address. EXECUTE used the code field address. To compound the problem, the words CFA, PFA etc from fig-Forth were eliminated (so there was no Standard way to get from one of these addresses to another). Forth-83 chose to make all operations based on a single address associated with each word (the "compilation address") [which, in every implementation I've seen, is the cfa]. [None of the reports from ANSI have indicated how this difference between '79 and '83 is being handled] STATE-SMART WORDS The Forth-83 team felt it objectionable to use the same name for two totally different actions. Words like ' which had different actions depending on STATE were replaced by a pair ' and [']. [None of the reports from ANSI have indicated how this difference between '79 and '83 is being handled] DO..LOOP The Forth-79 loop was apparently constructed in the days when 32k was considered a lot of memory. LOOP made a signed comparison of the loop index and limit. This meant that, for a 16-bit system, 32800 32600 DO I . LOOP would print 32600 and stop [32800 = -32736] The Forth-83 team redefined DO and LOOP to remove this unusual behavior. They also provided a conceptual base (the number circle) for understanding how loops operate -- and a consistent "crossing the boundary" exit condition for all forms of the LOOP construct. They also decreed that LEAVE cause an immediate exit from the loop (rather than take effect only at LOOP when the test is made). [None of the reports from ANSI have indicated how this difference between '79 and '83 is being handled] DIVISION One source of misunderstanding should be cleared up before going further: Numbers and their arithmetic are not within the domain of computer language teams to define. Some think numbers were created by God -- others by the mathematicians of antiquity. In any case, they exist "out there" and must be treated as given. Computers cannot represent numbers exactly as they are understood in mathematics. Only a subset of the integers can be represented. It must be clear to the user which subset is represented and exactly how the arithmetic operations in the language differ from the corresponding operations in mathematics. It is expected that the computer arithmetic will be as close as possible to "real" arithmetic. In mathematics frequent use is made of the fact that, given any two integers a and b (with b not zero) there are integers q and r so that (1) a = bq + r and (2) 0 <= |r| < |b| . Algorithms in which this occurs can present both positive and negative values of a and b. Often only the fact that (1) and (2) are satisfied is important [thus however MOD is defined, it is important that / is consistent with it]. There are, however, classes of algorithms in which a particular remainder is needed. When b is positive, the two most important choices for r are: a. 0 <= r < b ( non-negative r ) b. -b/2 < r <= b/2 ( smallest magnitude r ) Forth-79 division is "rounded to zero" -- it does not give either of these. The use of "rounded to zero" division always required a readjustment of the remainder. The "floored" division in Forth-83 always yields the more useful form a. for the remainder. After having used both Forth-79 and Forth-83 for a number of years, it is fair to say that the Forth-79 division really has no useful mathematical properties. It is only an accident of history that it has been used. I can't think of a single case where "rounded to zero" arithmetic is preferable to "floored". [The use of "floored" division is, as far as I'm concerned, just another small improvement of Forth over other languages -- and of Forth-83 over Forth-79. But here is a personal opinion: If there are compelling reasons for going back to the older division, it would be preferable to do that than to have /MOD left implementation dependent. / is the symbol everyone uses for division -- and will continue to use. Progress in Forth depends on the ability of people to share code fragments more than complete applications. It will be a great blow to progress if the meaning of very basic words is left floating.] PICK, ROLL In applications which require everything to be left on the stack, these words can be useful. In Forth-79 these were indexed at 1. In Forth-83 they became indexed at 0. [This is one that I honestly don't understand. Apparently the Forth-83 people think of the argument as an offset -- so the top of the stack is 0 and OVER is 1 PICK.] Final Comment: My switch to Forth-83 was prompted by a crisis: our courses were being switched to a micro-computer lab and the vendor of the Forth-79 I had used for years for research suddenly turned from Dr. Jekyll to Mr. Hyde. Apparently he intended to finance a trip to Hawaii (for his entire company) on the profits from my course. I vowed henceforth to stick to Microsoft, Borland, or public domain! I quickly acquired F83 and a copy of the Forth-83 Standard document. It soon became clear that I had a lot of re-writing to do (being able to run old code using a "prelude" was not good enough -- instructional material, in particular, had to correspond to what was found in books and on the system in use). Updating to a new Standard is not easy -- and, I must admit, I came to my first meeting with Guy Kelly with a chip on my shoulder. After switching, however, I was pleased with F83 and I found that most of the changes made by the Forth-83 team were for the better. I feel that the Forth-83 team left Forth a stronger language. Tweaking the language itself rather than using it to do something is a disease that seems to afflict the Forth community. I do not share the idea that the basic parts of the language should be constantly "under construction". I also feel that any proposed new addition to the language should be implemented on many different systems and tested (by many people) for several years before even being considered for incorporation in a new Standard. Once every 10 years we should meet. We should select the best of the changes and improvements that have been proposed and tested. We should *all* rewrite our systems to comply with the new Standard. And we should use our new found portability to cooperatively build structures larger than the wheel. John J Wavrik jjwavrik@ucsd.edu Dept of Math C-012 Univ of Calif - San Diego La Jolla, CA 92093
peter@ficc.ferranti.com (Peter da Silva) (07/16/90)
In article <11887@sdcc6.ucsd.edu> ir230@sdcc6.ucsd.edu (john wavrik) writes: > STATE-SMART WORDS > The Forth-83 team felt it objectionable to use the same name for > two totally different actions. Words like ' which had different > actions depending on STATE were replaced by a pair ' and [']. From rumors around at the time, basically Chuck Moore found state-smart words objectionable and convinced enough other people to get this through. Chuck Moore's own product, PolyForth, was pretty primitive... and the lack of state smart words and nesting checking for BEGIN/IF/DO were the worst part of it. My own reaction to dropping state-smart words was negative, to say the least. You quibbled over the semantics of NOT (I happen to agree with you there, by the way) based on human factors. Well, human factors argue for making the same word have the same semantics whether in compile state or interpret state. {." foo"} should no more have to be changed in a definition than {3 .}. Fixing DO loops and removing the conflict between {'} and {-find} were pretty nice features. I much prefer floored division. A lot of the F83 changes were positive... though the cosmetic changes (for example, from -dup to ?dup) seemed pretty arbitrary. But getting rid of state-smart words was a distinct step backwards in the name of purity. -- Peter da Silva. `-_-' +1 713 274 5180. <peter@ficc.ferranti.com>
ForthNet@willett.UUCP (ForthNet articles from GEnie) (07/18/90)
In <GIP4+J3@xds13.ferranti.com>, peter@ficc.ferranti.com (Peter da Silva) writes: > My own reaction to dropping state-smart words was negative, to say the > least. You quibbled over the semantics of NOT (I happen to agree with > you there, by the way) based on human factors. Well, human factors argue > for making the same word have the same semantics whether in compile > state or interpret state. {." foo"} should no more have to be changed > in a definition than {3 .}. Ok, I'm a novice at the trickier aspects of Forth. If {'} is STATE-SMART, then the sequence ' CREATE will behave the same when compiled as when interpreted (leave some kind of address related to CREATE on the stack)? If you have that, then you need some OTHER word which can be compiled and when executed will put the address of the word next found in the input stream onto the stack. As I see it you still need two words. It seems cleaner and simpler, to me, to have two state-less words that one state-smart word and another one that is state-less (but only used in definitions?). I think I can see the point of your analogy with {3 .}. My reply to that is that the analogy is based on a flaw. The flaw (IMO) is that you should look at {'} *not* as a word that reads the word following it in the input stream at the point the ' occurs, but rather as a word that reads the next word in the input stream when it is executed. I find your position on state-smart words rather puzzling because it seems to me that Forth normally goes out of its way to be simple and transparent. State-smart-ness, to me, says that Forth is smarter and knows more about what the programmer wants than the programmer does; i.e. the programmer is too dumb to understand the difference between interpreting and compiling. I hope that I haven't just set up a straw man in order to knock it down. I must be misunderstanding something somewhere, but don't know what yet. -Doug ----- This message came from GEnie via willett through a semi-automated process. Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu