Proposal: [60] Tighten the specification of SYNONYM (version 1)
This proposal has been moved into this section. Its former address was: /standard/tools/SYNONYM
This page is dedicated to discussing this specific proposal
ContributeContributions
GerryJackson
[60] Tighten the specification of SYNONYM (version 1)Proposal2018-06-08 10:09:18
Problem
Since SYNONYM has been incorporated into the Forth 2012 standard a number of use cases have been discussed that can result in different Forth 2012 systems giving different results. Therefore the specification for SYNONYM needs to be tightened to either specify the results of those cases or to make them ambiguous conditions. This RfD addresses those use cases and proposes solutions.
Terminology: in this RfD given this definition: SYNONYM BAR FOO FOO will be referred to as the original word, BAR as the synonym.
The guiding principle in this RfD is one of 'least surprise to the user'. Following use of SYNONYM a reasonable user expectation is that the synonym can be used in exactly the same way as the original word: the functionality and usage of them should be identical, the same operations should be applicable to them and they should have the same restrictions on usage.
Six aspects of the use of SYNONYM have identified that need to be clarified in the standard.
1) Restrictions (ambiguous conditions).
Given SYNONYM NEW-TO TO then ' NEW-TO is not designated an ambiguous condition by the standard whereas ' TO is
This particular example demonstrates that a synonym should inherit all the restrictions placed on the original word.
2) Values (VALUE, 2VALUE and FVALUE)
Given 123 VALUE FOO SYNONYM BAR FOO The view of the current Forth 2012 committee is that: 456 TO BAR is not permitted by the standard. but of course 456 TO FOO is permitted which may or may not result in FOO and BAR containing the same value.
Contrast this with synonyms of variables where storing a new value in a variable can be done on either the original word or the synonym and, in either case, their contents remain identical.
Therefore the guiding principle indicates that it should be legal for TO to be applied to the synonym of a value and that the values of the original word and its synonym should remain in step whichever word is updated using TO.
3) Deferred Words
Given DEFER FOO SYNONYM BAR FOO
As with TO above, writing ( xt ) IS BAR is not allowed whereas ( xt ) IS FOO is permitted and executing FOO is not guaranteed to give the same result as executing BAR
Similarly there are problems with DEFER!, DEFER@ and ACTION-OF ' some-word ' BAR DEFER! ' BAR DEFER@ and ACTION-OF BAR are invalid as BAR was not defined by DEFER
After ' some-word ' FOO DEFER! FOO and BAR are not guaranteed to hold the same xt
The guiding principle indicates it should be legal for IS, DEFER@, DEFER! and ACTION-OF to be applied to the synonym of a deferred word and for the XTs held by the synonym and original deferred word to be kept in step following the use of IS or DEFER! on either the synonym or original deferred word.
4) CREATE and >BODY
Given CREATE FOO SYNONYM BAR FOO should ' FOO >BODY and ' BAR >BODY give the same result?
At present ' BAR >BODY is an ambiguous condition since BAR was not defined directly via CREATE
This violates the guiding principle. Therefore >BODY should work on the synonym and the result should be the same address as for >BODY on the original word.
5) CREATE and DOES>
Given : DOESER DOES> ... ; CREATE FOO (zero or more definitions) SYNONYM BAR FOO DOESER should the use of DOESER be valid and, if so, should it operate on both FOO and BAR?
The current position in the standard is that it is invalid as it violates the rule that DOES> operates on the previous definition which has to have been CREATE'd.
If there are no definitions between CREATE FOO and SYNONYM BAR FOO then in some systems it is possible for DOES> to change the behaviour of both FOO AND BAR. But, in the general case if not impossible, that would cause severe implementation difficulties.
Therefore the guiding principle should be ignored in this case and applying DOES> to a synonym should be an ambiguous condition.
6) NAME>STRING
Given : FOO ... ; SYNONYM BAR FOO
TRAVERSE-WORDLIST will produce a name token for FOO and BAR. What result should NAME>STRING give for the name tokens of FOO and BAR?
In this case it seems clear that applying NAME>STRING on:
- FOO's name token should be "FOO"
- BAR's name token should be "BAR" Any other result would be surprising (remember that FOO and BAR may be in different wordlists)
Solution
Follow the recommendations listed in the Problem section above. See the proposal below.
Remarks
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 identical xts are not required
SYNONYM is already forbidden on locals due to the prohibition on definitions inside a colon definition. But that could usefully be noted in a rationale.
Some of the proposed changes could be regarded as bad practice e.g. changing the synonym of a deferred word also changes the original word could be regarded as a hidden side effect, but this already possible with synonyms of variables and Forth is a sharp knife ...
Banning DOES> on a synonym of a CREATEd word is similar to banning IMMEDIATE in that both alter the characteristics of the preceding definition.
Reference Implementation
Not applicable - requires detailed knowledge of the system
Test Cases
1 VALUE val
T{ SYNONYM synval val -> }T
T{ val synval -> 1 1 }T
2 TO val
T{ synval -> 2 }T
T{ 3 TO synval -> }T
T{ val synval -> 3 3 }T
\ Similarly for 2VALUE and FVALUE
DEFER def :NONAME 4 ; IS def
T{ SYNONYM syndef def -> }T
T{ def syndef -> 4 4 }T
T{ :NONAME 5 ; IS syndef }T
T{ def syndef -> 5 5 }T
:NONAME 6 ; CONSTANT defxt
T{ defxt ' syndef DEFER! -> }T
T{ def syndef -> 6 6 }T
T{ ' syndef DEFER@ ' def DEFER@ -> defxt DUP }T
T{ ACTION-OF syndef -> defxt }T
CREATE cre
T{ SYNONYM syncre cre -> }T
T{ ' cre >BODY ' syncre >BODY = -> TRUE }T
\ Testing NAME>STRING is complicated by the facts that:
\ - TRAVERSE-WORDLIST is the only way to get a name token
\ - the order of nt's provided by TRAVERSE-WORDLIST is undefined
\ - names may be stored in the dictionary in upper or lower case
\ If anyone can suggest a simpler test please post it
WORDLIST CONSTANT synwl
GET-ORDER synwl SWAP 1+ SET-ORDER DEFINITIONS
CREATE n>s1
SYNONYM syn-n>s1 n>s1
PREVIOUS DEFINITIONS
: >lower ( ch -- ch' )
DUP 'A' 'Z' 1+ WITHIN IF BL OR THEN ;
\ Case independent string comparison
: i$= ( caddr1 u1 caddr2 u2 -- f ) \ f = TRUE if strings are equal
ROT OVER <> IF DROP 2DROP FALSE EXIT THEN
0 ?DO
OVER C@ >lower OVER C@ >lower <>
IF 2DROP FALSE UNLOOP EXIT THEN
CHAR+ SWAP CHAR+
LOOP 2DROP TRUE
;
: get-name ( nt -- caddr u true ) NAME>STRING TRUE ;
: check-names ( caddr1 u1 caddr2 u2 -- f1 f2 )
DUP 4 > IF 2SWAP THEN ( -- "syn-n>s1" "n>s1" )
S" n>s1" i$= >R
S" syn-n>s1" i$= R>
;
T{ ' get-name synwl TRAVERSE-WORDLIST check-names -- TRUE TRUE }T
\ Can't test DOES> on a synonym as there is no portable way to test ambiguous conditions`
Experience
GForth 0.7.9_20171101, VFX Forth 4.72, author's personal system run all test cases Win32 Forth 6.15.04 runs the test cases except for NAME>STRING (not implemented) SwiftForth 3.7.2 hasn't implemented SYNONYM Other systems not tried.
Proposal
In the Forth 2012 Standard document make the following amendments:
Section 15.6.2.2264 SYNONYM
If oldname was created by VALUE, 2VALUE, FVALUE or DEFER then the value held by newname shall be identical to that held by oldname at all times even if TO, IS or DEFER! is applied, as appropriate, to oldname or newname.
If oldname was defined using DEFER then DEFER@ and ACTION-OF applied to oldname shall produce the same xt as DEFER@ and AACTION-OF applied to newname
If oldname was created by CREATE then ' newname >BODY shall result in the same address as that given by ' oldname >BODY.
NAME>STRING shall produce the name of newname/oldname when applied to the name token of newname/oldname respectively.
All ambiguous conditions applicable to oldname shall apply to newname.
An ambiguous condition shall exist if DOES> is applied to newname.
Section 6.2.2295 TO
Amend the end of the Interpretation: and Compilation: paragraphs to read ... if name was not defined by a word with "TO name run time" semantics or the synonym of such a word.
Section 6.2.1725 IS
Amend the end of the Interpretation: and Compilation: paragraphs to read ... if name was not defined by DEFER or the synonym of such a word.
Sections 6.2.1175 DEFER! and 6.2.1177 DEFER@
Amend the end of the first paragraph to read ... word defined by DEFER or the synonym of such a word.
Section 6.2.0698
Amend the end of the Interpretation and Compilation paragraphs to read ... not defined by DEFER or the synonym of such a word, or if ...
Section 6.1.0550 >BODY
Amend the end of the description to read ... defined via CREATE or the synonym of such a word.