Digest #36 2018-06-09

Contributions

[60] 2018-06-08 10:09:18 GerryJackson wrote:

proposal - Tighten the specification of SYNONYM (version 1)

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.

Replies

[r141] 2018-06-07 09:50:11 JennyBrien replies:

proposal - find-name

Stephen Pelc wrote

The NDCS VFX works fine with FIND.

Does the same FIND allow NCDS words to be used wirh legacy code that either EXECUTEs or COMPILE,s the xt returned?

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.

Does this mean that

synonym foo bar

' foo  ' bar = .
-1 ok

? That seems sensible if it can be done. It means syonyms of CREATE ... DOES> words should simply work with definitions that use ' >BODY and, by extension, synonyms of deferred wordsand values should also work as expected. It also makes it clear that you can't change the definition of a synonym with IMMEDIATE or DOES> because that would affect the original.

We have to recognise that people with xt-based systems are not going to abandon them, they will simply use FIND-WORD or some such that returns an xt.

Of course, but the name token stuff has been around for twenty years and more now, and it's not going away either.

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.

Practically, we need to clarify when FIND-WORD is being used as a synonym for FIND-NAME and when for FIND-NAME NAME>INTERPRET . Whether an xt should be COMPILE,ed or EXECUTEd is determined by the dictionary header that returned it, not by the bare xt itself.

Note that the compilation issues caused by NDCS ("non-default compilation semantics") have taken 20+ years to emerge.

That's because normally it makes no sense to execute an NCDS word except as a part of normal compilation. So you could get away with defining COMPILE, as meaning 'perform the compilation semantics' and using LITERAL EXECUTE when you meant 'append the execution semantics.'


[r142] 2018-06-07 13:46:17 StephenPelc replies:

proposal - find-name

Jenny said: Stephen Pelc wrote

The NDCS VFX works fine with FIND.

Does the same FIND allow NCDS words to be used wirh legacy code that either EXECUTEs or COMPILE,s the xt returned?

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 ; 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.

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. Note that my exploration of NDCS is not about preserving single xt and so on, it was an attempt to understand compilation in Forth. One of the side effects of this exploration is the realisation that STATE-smart words can be re-implemented as dual-behaviour words which are standard compliant.


[r143] 2018-06-07 19:43:58 JennyBrien replies:

proposal - find-name

Note that my exploration of NDCS is not about preserving single xt and so on, it was an attempt to understand compilation in Forth. One of the side effects of this exploration is the realisation that STATE-smart words can be re-implemented as dual-behaviour words which are standard compliant.

Yes, but your method and Anton's sèem to imply different methods of specifying NDCS. Your method requires that the compilation xt. expects the interpretation xt on the stack. His (I think) requires that it doesn't.


[r144] 2018-06-07 23:47:38 StephenPelc replies:

proposal - find-name

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. Anton's implementations hide most of this.


[r145] 2018-06-08 12:03:52 BerndPaysan replies:

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 use FIND-NAME as test vehicle.

A reference implementation of FIND-NAME using TRAVERSE-WORDLIST should be available in the FIND-NAME proposal soon (Anton is wrong that FIND-NAME-IN requires carnal knowledge).


[r146] 2018-06-08 12:18:02 BerndPaysan replies:

proposal - find-name

Full reference implementation using TRAVERSE-WORDLIST:

\ find-name and find-name-in

\ this file is in the public domain

: >lower ( c1 -- c2 )
    dup 'A' 'Z' 1+ within bl and or ;
: istr= ( addr1 u1 addr2 u2 -- flag )
   rot over <> IF  2drop drop false  EXIT  THEN
    bounds ?DO
        dup c@ >lower I c@ >lower <> IF  drop false  unloop  EXIT  THEN
        1+
    LOOP  drop true ;

: find-name-in ( addr u wid -- nt / 0 )
    >r 0 -rot r>
    [: dup >r name>string 2over istr= IF
            rot drop r> -rot false
        ELSE  rdrop true  THEN
    ;] swap traverse-wordlist 2drop ;
: find-name {: c-addr u -- nt | 0 :}
    get-order 0 swap 0 ?do ( widn...widi nt|0 )
        dup 0= if
            drop c-addr u rot find-name-in
        else
            nip
        then
    loop ;

[r147] 2018-06-08 13:55:28 GeraldWodni replies:

example - Need lock on already posted comments

Well if your browser is properly configured and a back-action would redo a POST, a warning dialog along ...Resubmission... should be displayed. If you choose to ignore that warning, the form is resubmitted and thereby the item is re-sent and you have the second post again.

New websites cirumvent this by using XHR to transmit their content, but as this website chooses to also work without javascript, this feature would require quite some effort for a very limited usecase.

So please do not ignore theese dialogs for now ;)


[r148] 2018-06-08 14:04:33 GeraldWodni replies:

requestClarification - How to change email address

Your email adress has been changed!

Asking here for a change or writing me an email is perfectly fine, I just did not have time to implement a email changing feature which involves a verification email.


[r149] 2018-06-08 14:32:03 StephenPelc replies:

example - Need lock on already posted comments

Browser is Chrome and no dialog popped up.


[r150] 2018-06-08 14:32:15 StephenPelc replies:

example - Need lock on already posted comments

Browser is Chrome and no dialog popped up.


[r151] 2018-06-08 14:37:12 StephenPelc replies:

example - Need lock on already posted comments

Let me know what to configure.