Digest #37 2018-06-28
Contributions
The description doesn't make it clear that the string is prepended to the existing contents of the pictured output buffer. That can be deduced from the reference implementation but a user shouldn't have to do that.
Also the test does not make it clear. Suggest adding a test along the lines:
T{ <# 123 0 #S S" Number: " HOLDS #> " Number: 123" COMPARE -> 0 }T
Replies
Thank you
I've only just realised that comments on this topic were here. Here is a post I made on the Yahoo Forth 200X group on 13 May copied here for completeness.
I've just realised what you were probably referring to with the [ELSE] ... [THEN]. That is specifically tested in the toolstest.fth file.I'd be surprised if it occurred in any other file.
That is just testing [ELSE] as written in the standard and I don't see any reason to remove it unless the specification for [ELSE] is rewritten to forbid it. Another silly thing is tested, [THEN] is a noop, so a lone [THEN] is valid and tested.
There are other dubious things tested in the test suite e.g. in coreplustest.fth multiple ELSE's in IF statements are tested e.g. ... IF...ELSE ... ELSE... ELSE...THEN ... which is perfectly valid standard Forth according to the specification for ELSE.
I believe test programs should test what's written in the standard, corner cases and sillinesses as well as usual usage.
proposal - Tighten the specification of SYNONYM (version 1)
So either quoting a synonym returns the original xt or >BODY etc. are aware of synonyms and do the necessary adjustment?
What happens when you make a synonym of another synonym?
proposal - Tighten the specification of SYNONYM (version 1)
This should pass (does so in Gforth):
create foo
synonym bar foo
t{ ' foo -> ' foo }t
synonym baz bar
t{ ' baz -> ' foo }t
No, >body
and friends should not know anything about synonyms. The only place where synonym deserve special attention is in name>compile
and name>interpret
. Since this proposal is to tighten down synonym
, it's better to make clear that it mandates where the treatment of synonyms has to happen.
proposal - Tighten the specification of SYNONYM (version 1)
Can I have an edit button?
First test shall be
t{ ' bar -> ' foo }t
proposal - Tighten the specification of SYNONYM (version 1)
For the test cases: Since we have a proposal for
FIND-NAME
to produce NTs, you can useFIND-NAME
as test vehicle
Yes that certainly simplifies things. The test for FIND-NAME
of synonyms then becomes (i$= the case independent compare is still needed):
CREATE n>s1
SYNONYM syn-n>s1 n>s1
T{ S" n>s1" 2DUP FIND-NAME NAME>STRING i$= -> TRUE }T
T{ S" syn-n>s1" 2DUP FIND-NAME NAME>STRING i$= -> TRUE }T
proposal - Tighten the specification of SYNONYM (version 1)
First test shall be:
t{ ' bar -> ' foo }t
This requires the xt's to be the same, Anton didn't think that was necessary - I don't mind either way
proposal - Tighten the specification of SYNONYM (version 1)
Letting all synonyms have the same xt is certainly a good solution. Should we require it? I don't know a reason for or against (in particular, I don't think that there is a system that has SYNONYM where synonyms of the same word have different xts), so in the spirit of tightening, we probably should require it.
In the proposal, separate the TO cases from the IS/DEFER! to make it watertight.
AACTION-OF should be ACTION-OF
"shall": The style for ambiguous conditions has been: "An ambiguous condition exists if...".
6.2.0698: Mention that this is ACTION-OF
Put the test cases in code style (surround with ``` lines) or in a separate file.
There is no need to test for ambiguous conditions. These are the cases that a standard program should avoid.
proposal - Tighten the specification of SYNONYM (version 1)
Anton wrote:
Letting all synonyms have the same xt is certainly a good solution. Should we require it? I don't know a reason for or against (in particular, I don't think that there is a system that has SYNONYM where synonyms of the same word have different xts), so in the spirit of tightening, we probably should require it.
I don't see any objection. I picture SYNONYM as being equivalent to creating an identical header with a possibly different name in a system with detatched headers. I.e. it points to the same code and data space. I think all the restrictions above flow naturally from that.
I think there was, years ago, a proposal for a word ALIAS ( xt name -- ) , that only copied the execution and created a defition with default compiling semantics. Was it suggested that should return the same xt when ticked? I don't think it's possible, under VFX, to have two words with the same xt but different compiling semantics, though I could be wrong.
proposal - Tighten the specification of SYNONYM (version 1)
Yes, different systems would behave differently for ALIASes of immediate words, and when applying IMMEDIATE to an alias; and in particular, one passes an xt to ALIAS, and in Gforth, the xt is not associated with immediacy. That's why we standardized SYNONYM, no ALIAS, and why applying IMMEDIATE to a synonym is ambiguous.
The sole reason for FIND-NAME is to allow for multiple words with the same xt, i.e. the nt identifies a named word and xts identify the actions.
Yes, words with different names and the same interpretation semantics xt are a reason for FIND-NAME, but not the only one.
The main reason is that it (together with the already-standardized NAME>INTERPRET and NAME>COMPILE) provides a good factoring that separates the jobs ob looking up the named word (FIND-NAME), accessing the interpretation semantics (NAME>INTERPRET) and accessing the compilation semantics (NAME>COMPILE) into separate words.
This is the replacement for FIND that you asked for.
We have to recognise that people with xt-based systems are not going to abandon them
Nobody is asking them to, whatever you mean with "xt-based system". The only thing that FIND-NAME NAME>INTERPRET NAME>COMPILE etc. are not a good fit for are multi-header systems like cmForth and Mark Humphries' system (but I have outlined how to implement these words on the latter).
I really feel that we should slow down and resolve issues such as NDCS words before we redesign the text interpreter. Given recognisers, this may be too late, but we need to work our way through the issues before we make changes that we may regret. Note that the compilation issues caused by NDCS ("non-default compilation semantics") have taken 20+ years to emerge.
These issues emerged in my experience in 1996 (two years after Forth-94 was released), and FIND-NAME etc. have been implemented and used in the text interpreter of Gforth since then. We have collected experience with them since then (i.e., for 22 years), for several implementation approaches for NDCS words (including the current one in Gforth, which can be described as "xt-based"), and the experience is that these words provide a good implementation-independent interface.
Given that the problem has been recognized by the time of Forth-83 (35 years ago) at the latest, this solution has 22 years of experience, and you asked for a FIND replacement, your call for slowing down even more is not helpful. These issues have been discussed again and again for a long time, so they are not going away; therefore we need to go forward. You asked for this proposal, here it is!
That's one of the results of permitting NDCS words that are not IMMEDIATE. If we keep the restriction that COMPILE, must not parse or have additional stack effects, we need a word, then we can either introduce a compiling word that can parse, e.g. : compile-word \ ix xt -- jx \ *G process an XT for compilation. dup ndcs? \ NDCS or normal if ndcs, else compile, then ;
The other option is to use EXECUTE as the word that can parse and have additional stack effects. Of course then FIND will report these NDCS words as "immediate", and will return different xts in different STATEs for NDCS words, as allowed by Forth-94 and Forth-2012.
or we could just lift the restrictions on COMPILE, so that the requirements of NDCS can be supported by COMPILE, itself. The second option leads to very little change. In the VFX with COMPILE-WORD, the word NDCS, is used only once in the kernel and COMPILE-WORD replaces COMPILE, in the vast majority of cases.
The real requirement (aka restriction) of COMPILE, is that it appends the same semantics that EXECUTE executes, i.e., that it is equivalent to
: compile, postpone literal postpone execute ;
That it has the stack effect ( xt -- ) and that it does not parse follows from that. And I have seen quite a lot of uses of COMPILE, that make use of this equivalence (most uses of COMPILE, that are not in text interpreters).
It is worth noting that VFX ran with this non-compliant COMPILE, for several years and the only complaint about it came from Anton ... because it was non-compliant.
And lots of people report "no problems" with STATE-smart words. Others, like me, tripped over them.
A broken COMPILE, would not be so bad if it only affected VFX and only S" and TO. But the disease was spreading to Gforth, where not just a few words with broken COMPILE, were implemented, but many; and, in addition, it contained defining words that made each of their children have a broken COMPILE,. I am not sure if this disease has been fully cured yet.
My view is that if you want dual-behaviour words then you need to implement the consequences outlined in my paper. However this is implemented, a way of performing the word that I called NDCS, is required.
This view is refuted by the many systems that have implemented dual-behaviour words correctly, but differently from what you outlined in the paper, and in particular, without having a word like your NDCS,.
In any case, FIND-NAME NAME>INTERPET NAME>COMPILE abstract from the implementation (except for being a better fit for a single-header system than for a multi-header system), as demonstrated by the fact that they have been implemented on several different systems, and can be implemented on VFX.
proposal - Tighten the specification of SYNONYM (version 1)
I see. I was thinking of the twin xt syntax for defining dual word as a factor of SYNONYM
i-xt c-xt DUAL: *name* defines a dual word
0 c-xt DUAL: *name* defines a compile-only word
xt dup DUAL: *name* defines an immediate word
xt. ALIAS: *name* defines a default word
But I don't see how to make it work with VFX
proposal - Tighten the specification of SYNONYM (version 1)
Your DUAL: is quite simular to Gforth's INTERPRET/COMPILE:. In a system where the compilation semantics hangs on the i-xt, such a word would either set the compilation semantics of other words with the same i-xt, or would have to introduce a new i-xt (e.g., a deferred word), but then it becomes harder to use this word for defining a synonym. I guess we won't be seeing such a word standardized, though.
ChangeLog
2018-05-17: Wording changes following the suggestion by JennyBrien
2018-05-29: Specify FIND for words without interpretation semantics, and loosen it for TO IS ACTION-OF. Added Remarks section for a rationale of these additions.
2018-05-23: Initial version
Problem
The existing specification of FIND is unclear wrt what xts are returned under what conditions. It also uses a different notion of immediacy from the one in the Definition of Terms. From the rationale of FIND, it is obvious that cmForth inspired the idea that two different xts can be returned. The rationale of COMPILE, shows that the intention is that FIND can be usable for the user-defined text interpreter. But FIND as specified does not guarantee that. This proposal would fix this problem; it is also phrased in a way that includes systems like cmForth and Mark Humphries' system.
Proposal
Replace the text in the specification of FIND with:
Find the definition named in the counted string at c-addr. If the definition is not found, return c-addr and zero. If the definition is found, return xt 1 or xt -1. The returned values may differ between interpretation and compilation state:
In interpretation state: If the definition has interpretation semantics, FIND returns xt 1 or xt -1, and EXECUTEing xt performs the interpretation semantics of the word. If the definition has no interpretation semantics, FIND may produce c-addr 0; if it produces xt 1 or xt -1, EXECUTEing xt performs a system-dependent action.
In compilation state, the returned values represent the compilation semantics: if xt 1 is returned, then EXECUTEing xt performs the compilation semantics; if xt -1 is returned, then COMPILE,ing xt performs the compilation semantics.
If the definition is for a word for which POSTPONE is ambiguous, it is ambiguous to perform the xt returned by FIND in a STATE different from the STATE during FIND.
In 4.1.2 Ambiguous conditions, add the ambiguous condition above, and remove "6.1.1550 FIND" from
attempting to obtain the execution token, (e.g., with 6.1.0070 ', 6.1.1550 FIND, etc. of a definition with undefined interpretation semantics;
Remarks
The removal of FIND from the clause in 4.1.2 ensures that we can text-interpret (in compile STATE) words without interpretation semantics, such as IF. The description of the behaviour of FIND for these words in interpretation STATE allows implementations that do not find such words, implementations that return the xt for an error, implementations that return the xt for the compilation semantics, and implementations that return the xt for some system-specific interpretation semantics.
The ambiguous condition allows STATE-smart implementations of TO, IS and ACTION-OF (as Forth-94 and Forth-2012 do).
Note that this does not allow STATE-smart implementations of words without interpretation semantics (e.g., IF), but then, that's already forbidden by POSTPONE and [COMPILE].
I have adopted the reference implementation by Bernd Paysan and added a few adjustments. I have also added more test cases that test using FIND-NAME for a simple variant of a user-defined text interpreter, and using it for interpreting all the hard cases: S" and TO (both interpretation semantics and compilation semantics) and locals (definition, use, and TO semantics). The result works on development Gforth (with both the Gforth implementation of FIND-NAME and with the reference implementation), and on VFX 4.72.
You can find them here: Reference Implementation, Testcases
One wrinkle is that you need carnal knowledge for proper handling of locals in FIND-NAME. This has been included for Gforth and VFX in the reference implementation, but not (yet) for other systems.
Sorry the test should read:
T{ <# 123 0 #S S" Number: " HOLDS #> S" Number: 123" COMPARE -> 0 }T