Digest #16 2017-01-01
I just wrote a long reply, taking my time. At the end my session had timed out, the system asked for authentication and presented an empty text field instead of the result of my long editing session. Please fix:
longer session time.
Upon session timeout, preserve the state of the session across the authentication screen.
We already have SF@ SF! DF@ DF!, and they put standard floats on the FP stack, not single or double floats. So you would need other words to put single and double floats on the FP stack.
Also, we have standardized a separate FP stack, because writing portable programs for a shared FP stack is not practical. For single and double floats it's probably best to use the same FP stack, with one FP stack item per single or double, like FP registers are organized on most architectures; of course, separate stacks for these types are also possible, but would require additional stack pointers and stack manipulation words.
None of these variants looks particularly attractive, which is probably why there is very little, if any, practice in this direction.
Reasons for hardware to have 32-bit FP numbers (and smaller):
Existing software uses it; and existing programming languages have types for it; I.e., continue a tradition that had technical reasons once upon a time; and 32-bit FP is cheap to implement once you have implemented 64-bit FP. That's no reason to have it in Forth.
For vector operations you can deal with more values in the same amount of hardware. I don't see this as a reason to have it in Forth for scalar FP operations, because I don't think we should go for auto-vectorization in Forth. If we add vector operations to Forth, we can think about vectors of 32-bit FP numbers, but that's still no reason to have several scalar on-stack FP types.
Yes, TRAVERSE-DIR, and JOIN-PATH need to specify where the output string is and how long it lives. Also, the buffer handling of READ-DIR makes it hard to use properly. Better make an interface like
read-dir ( dir-id -- c-addr u ior )
where the resulting string lives until the next invocation of read-dir (for the same dir-id?), and c-addr u is 0 0 if there is no entry left.
On optimization: Stroustroup had a design rule when developing C++: a new language feature should not slow down the implementation of other, previously existing language features; if we follow this rule (and it sounds pretty sensible for a language like Forth), SYNONYM should not slow down the implementation of DOES>.
In particular, the ability to change a CREATEd word later (after having used it or already changed it once with DOES>) is something that is rarely used in Forth, and changing it through a synonym is likely to be used even more rarely; if it is really desired, this functionality can already be achieved with, e.g., DEFERred words. So the ability to change a CREATEd word later through a synonym would cost performance without gaining capability, and, in nearly all cases not even convenience.
[As an aside, this whole issue is another fallout of the design of CREATE...DOES> of having a word first and changing its behaviour later, which also makes problems in connection with flash-based Forth systems and with having an intelligent COMPILE,; a better design would fix the behaviour at creation time, which would avoid all three problems.]
Clone or reference: This plays a role for mutable words like variables, values, and deferred words. It seems to me that the intention is to be a reference; this is already clear for variables (executing the xt must give the same address), but for values and deferred words the specification is not yet specific enough to make that airtight.
However, when it comes to NAME>STRING, we want the synonym to have it's own name and therefore it needs its own nt; that's the issue the A1 A2 example points out. In some systems (especially some that want to have NT=XT) the most straightforward implementation of SYNONYM might produce the same NT for A1 and A2, and then the output of W2 TRAVERSE-WORDLIST might be A1. Implementations of SYNONYM that get this right will either deviate from the NT=XT dogma or will incur some complications when implementing TO, IS, ACTION-OF, DEFER@, DEFER!, and >BODY.
Overall, the consensus for a tightened synonym seems to be:
The synonym inherits the properties of being defined by CREATE or DEFER, and any ambiguous conditions about ticking and POSTPONEing from the original.
Concerning DOES>, one must not apply that to a synonym, like IMMEDIATE.
TO, IS, ACTION-OF, DEFER@, DEFER!, >BODY are allowed on the synonym if they are allowed on the original, and produce the same results for the synonym as for the original.
NAME>STRING produces the name of the original for the original, and the name of the synonym for the synonym.
NAME>INTERPRET and NAME>COMPILE: if they produce the same values for the synonym as for the original, the DEFER@ DEFER! >BODY, and probably also TO, IS, ACTION-OF issues fall out for free. But I don't think we need to require that; if some system wants to produce different values, what's the harm (apart from the fact that it probably has a more complicated implementation of the words mentioned above)?
Did I forget anything?