SYNONYM

( "<spaces>newname" "<spaces>oldname" -- )

For both strings skip leading space delimiters. Parse newname and oldname delimited by a space. Create a definition for newname with the semantics defined below. Newname may be the same as oldname; when looking up oldname, newname shall not be found.

An ambiguous conditions exists if oldname can not be found or IMMEDIATE is applied to newname.

newname interpretation:

( i * x -- j * x )
Perform the interpretation semantics of oldname.

newname compilation:

( i * x -- j * x )
Perform the compilation semantics of oldname.

See:

Implementation:

The implementation of SYNONYM requires detailed knowledge of the host implementation, which is one reason why it should be standardized. The implementation below is imperfect and specific to VFX Forth, in particular HIDE, REVEAL and IMMEDIATE? are non-standard words.

: SYNONYM \ "newname" "oldname" --
\ Create a new definition which redirects to an existing one.
   CREATE IMMEDIATE
     HIDE ' , REVEAL
   DOES>
     @ STATE @ 0= OVER IMMEDIATE? OR
     IF EXECUTE ELSE COMPILE, THEN
;

ContributeContributions

GerryJacksonavatar of GerryJackson Incomplete specification of SYNONYMComment2016-11-22 10:02:04

Shouldn't the synonym of a word inherit the restrictions of the parent word. For example

SYNONYM NEW-TO TO

' NEW-TO \ Is apparently valid because it isn't forbidden whereas

' TO \ Is an ambiguous condition

Also this is not forbidden and would be rather confusing

SYNONYM TO TO

' TO

All that it needs is to add a sentence such as:

All ambiguous conditions applying to oldname, also apply to newname.

AntonErtlavatar of AntonErtl 2016-12-08 09:43:19

Good point.

Other, less urgent issues are inheritance of TO <name> semantics, and inheritance of the property of being a child of a CREATEd word. Any other issues?

AntonErtlavatar of AntonErtl 2016-12-08 14:33:37

Once the "child-of-CREATE" property can be inherited (for >BODY), we need to specify if the following is standard and what it does:

: foo does> drop ." foo" ; : bar does> drop ." bar" ; create a foo synonym b a bar a

We did not standardize using IMMEDIATE on a synonym, should we allow using DOES>?

GerryJacksonavatar of GerryJackson 2016-12-09 08:57:19

That's an interesting point. Your example works on my system, as does the following variation:

: foo does> drop ." foo" ;
create a foo
a                         \ Displays foo
: bar does> drop ." bar" ;
synonym a a
a                         \ Displays foo
bar a                     \ Displays bar
foo a                     \ Displays foo

Where bar is defined after a is created. If this usage is deemed standard it provides a way of changing the action of a create ... does> word retrospectively without the need for defer. This is something I have wanted to do in the past. It works on GForth too.

If nothing else ISTM that this could be useful when debugging. For example, during development : could be redefined to generate a create does> drop ... definition. When something goes wrong synonym could be used to alter a word's action to provide debugging information without having to recompile the system. I've not tried it but I don't see in principle why it wouldn't work. So I would support standardising the use of does> for synonyms.

As noted recently on comp.lang.forth is for deferred words also needs to be considered and probably defer@ and defer!.

GerryJacksonavatar of GerryJackson 2016-12-09 11:00:57

I was a bit premature with my suggestion - it only works on my system. If my example is amended to include a definition calling a before the use of synonym i.e.

: foo does> drop ." foo" ;
create a foo
: baz a ; baz                        \ Displays foo
: bar does> drop ." bar" ;
synonym a a
bar baz                              \ Displays bar on my system but not on GForth

bar Modifies the behaviour of baz on my system but not GForth or VFX Forth.

In your original example:

: foo does> drop ." foo" ; : bar does> drop ." bar" ; create a foo synonym b a bar a

VFX Forth bar doesn't change the behaviour of a or band so is different compared to Gforth. Win32 Forth is different as it crashes. So four systems with four different behaviours using does> on synonyms.

AntonErtlavatar of AntonErtl 2016-12-09 11:10:06

I guess my example works (as in "does not produce an error") in many systems, but what is the effect? Is A changed or is it not? Do we want to standardize one of these behaviours, or not. One reason not to guarantee changing A is that it disallows optimizing DOES>. E.g.,

: method create ... does> ... ;
method draw
: foo ... draw ... ;

Here the compiler can inline DRAW. That's no longer possible if DRAW can be changed later.

Currently only interpretation and compilation semantics is copied by SYNONYM, so the property of being defined by CREATE is not guaranteed to be copied, and the example is non-standard.

Yes, synonyms of DEFERed words is another good point.

Another issue: Consider

wordlist constant W1
wordlist constant W2
W1 set-current create A1
W2 set-current
W1 >order synonym A2 A1
:noname name>string type true ; W2 traverse-wordlist

Will this output A2 or A1? It seems to me that a basic invariant for traverse-wordlist is that, if you SEARCH-WORDLIST for the name produced by NAME>STRING in the traversed wordlist, you will find a word with that name, so it should output A2.

JennyBrienavatar of JennyBrien 2016-12-11 20:32:42

If you make a synonym of a word with private data (e.g. a VALUE, a DEFER, or something with CREATE DOES>) then the two words share that data. Any change in the original is reflected in the synonym. If you don't want that, then instead you create a new instance with the same defining word.

So, if that is what you want, do you also need words like TO and IS to be applicable to the synonym as to the original?

That's fairly easy for user-defined definers, I think: All you need do is state that ticking or FINDing a synonym returns the xt of the original. But I think we've already decided not to go that route, and Synonyms may return a different xt from their originals. In any case, the xt of a DEFER or a VALUE is no use for changing the data, so all the Standard data - setting words might have to be modified to allow for the possibility of synonyms.

In short, a Synonym has the same interpretation and compilation behaviour of the original, affecting the same internal data. Any other behaviour that the original may have result from it being defined using a particular defining word, and are not inherited by the synonym.

JennyBrienavatar of JennyBrien 2016-12-11 20:42:18

"Will this output A2 or A1? It seems to me that a basic invariant for traverse-wordlist is that, if you SEARCH-WORDLIST for the name produced by NAME>STRING in the traversed wordlist, you will find a word with that name, so it should output A2."

Of course. A synonym may have the same xt as the original, but I don't see how it could have the same name token and still be a different word.

GerryJacksonavatar of GerryJackson 2016-12-11 21:17:31

I don't think optimisation should be a significant driver in the functionality of a word - it may help swing the balance in some cases.

What do we mean by synonym? Given synonym B A

  1. is B a snapshot or clone of A that then has a future independent of what happens to A or
  2. is B a reference to A so that it shadows whatever happens to A
  3. or something in between.

Cloning is easy and doesn't require the use of synonym so meaning 2 should be the desired aim.

We have identified issues with values, deferred words, children of create ... does> ... words, inheritance of ambiguous conditions, and possibly wordlists.

Dealing with the latter first, I don't see what the issue is in your example - A2 is clearly defined in wordlist W2, the invokation of traverse-wordlist is only looking in W2 so why would anybody argue that A1 whould be displayed?

Putting that aside and considering synonym B A again:

For synonyms of colon definitions, variables and constants it seems clear that if A is later redefined then B still refers to the old definition of A as the alternative would go against Forth tradition.

For values the question is whether to A affects the value of both A and B or A alone. Similarly to B. If we want consistency with variables and constants then to A should change the value of both A and B and that is what I would expect.

The situation with deferred words doesn't seem so clear. It could be argued that if the action of A is changed by is or defer! then that is equivalent to redefinition of A and so should not change the action of B, and vice versa. Alternatively it could be argued that A is not really being redefined, it is more like a variable or value being changed and the change in behaviour is incidental, so both A and B should remain in step. I would favour the latter.

For children of create ... does> it seems to me that the best argument is that after A has been created and there have been later definitions then the action of A cannot be changed by an execution of does>. Defining synonym B A is such a later definition which should, therefore prevent the action of A being changed by does>. My feeling is that we should probably make applying does> to a synonym either ambiguous or forbid it. Changing the action of A could easily lead to obscure bugs in a program. Of course the same could be said for deferred words.

JennyBrienavatar of JennyBrien 2016-12-12 20:20:37

For values the question is whether to A affects the value of both A and B or A alone. Similarly to B. If we want consistency with variables and constants then to A should change the value of both A and B and that is what I would expect.

I agree with that, but the question I was asking was rather:

Given Value A Synonym B A Is TO B guaranteed to work?

I think it would naturally for a flag-setting TO but it may fail on some systems with a parsing TO,

Perhaps the most logical way to think of a Synonym is that it creates a header that returns the same values for NAME>INTERPRET and NAME>COMPILE as the original. (I'm not saying this is the only way it can be done, but it is a way that the Standard allows - I think).

These are the only values (apart from the NAME) that a Standard application can derive from the dictionary structure.

They are also set by:

DOES> associates the xt with an action that uses the data space address that it previously returned IMMEDIATE sets the compilation action to execute the xt COMPILES> (or SET-COMPILER whatever else we decide to set a particular non-default compiliation action.)

In each case they can only be set for the current definition, and are invariant once that definition is complete.

Given this a synonym is an exact substitute for the original, with the same Standard behaviour in all situations. For example, if the original can be ticked, then ticking the synonym returns the same xt. If ticking the original is an ambiguous condition, then a Standard program cannot tick the synonym, it may or may not respond in the same fashion as the the original (which may for example have been marked as 'compile-only') but that is beyond the scope of he Standard.

It doesn't seem to make much sense to combine SYNONYM with any of the other behaviour-setting words, because that implies you want something other than a synonym - something that can be provided in other ways:

Synonym B A DOES> C probably wouldn't work, or would change the definition of A, but the intention can be achieved by:

' A >BODY CONSTANT D : B D C ;

Synonym B A IMMEDIATE is trivially : B A ; IMMEDIATE

And these definitions, not being synonyms of the original, do not share its xt.

Where A is defined by a user-defined CREATE …DOES> word (there must be a shorter way of saying that) any word that uses >BODY to manipulate its data will naturally also work on its synonym, which returns the same data and therefore references the same data.

I'm assuming that words manipulate DEFER and the like (which need not use CREATE … DOES>) also access their data solely through their xt and therefore will work for a synonym that return the same xt. It's possible that IS, TO etc. need access to some other information in the dictionary header, so SYNOYNYM would need to be smart enough to build the appropriate header for words defined by each of the Standard defining words.

That's another reason why the definition of SYNONYM is implementation-dependent, but I can't quite believe that any implementation would do things in such a roundabout way.

ruvavatar of ruv 2016-12-13 12:10:12

People, don't you think that GitHub/ForthHub is more more convenient for such discussions?

GerryJacksonavatar of GerryJackson 2016-12-13 20:21:46

@JennyBrien

For values the question is whether to A affects the value of both A and B or A alone. Similarly to B. If we want consistency with variables and constants then to A should change the value of both A and B and that is what I would expect.

I agree with that, but the question I was asking was rather:

I was responding to Anton's message and hadn't seen yours before I submitted mine. I think we were writing a reply at the same time!

Given Value A Synonym B A Is TO B guaranteed to work?

Yes I think so.

I think it would naturally for a flag-setting TO but it may fail on some systems with a parsing TO,

The standard insists on a parsing to, see the specification for to, so we don't need to consider that.

As regards the rest of your reply I think I agree with much of it. My system, which has detached headers, simply provides the same xt for both B and A for synonym B A so anything that is done to A or B is done to both whether by does> to is or defer!. And that seems reasonable to me although I wouldn't object to does> being forbidden.

Actually I've just thought of another issue that would break my system, I think, and that is if we have the sequence

create A
\ Possibly more definitions etc but no application of DOES> to A
: X  does> ...  ;
synonym B A  X

i.e. A is not a create ... does> word. This may be a good reason for banning does>

@ruv I don't mind where the discussion is held. This site was set up specifically for the Forth 200X standard with a provision for comments, and so it is not unreasonable to have a discussion here.

JennyBrienavatar of JennyBrien 2016-12-14 20:35:29

The standard insists on a parsing to, see the specification for to, so we don't need to consider that.

It insists that a parsing TO be allowed - so the name must always follow directly, without another word or line break in between as is possible with a non - parsing TO.

As regards the rest of your reply I think I agree with much of it. My system, which has detached headers, simply provides the same xt for both B and A for synonym B A so anything that is done to A or B is done to both whether by does> to is or defer!. And that seems reasonable to me although I wouldn't object to does> being forbidden.

Actually I've just thought of another issue that would break my system, I think, and that is if we have the sequence

create A
 \ Possibly more definitions etc but no application of DOES> to A
: X  does> ...  ;
synonym B A  X

i.e. A is not a create ... does> word. This may be a good reason for banning does>

Either way, I think what happens here is that both A and B are set to do X. That is definitely a bad idea: the definition of a word (in this case A) should not change after it has been used - unless of course it's a Deferred word, where you state at the outset that that's your intention.

This case is covered. B has not been defined using CREATE, so the code is already non - Standard.

AntonErtlavatar of AntonErtl 2016-12-31 22:02:53

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?

Reply