20060821 First draft
Rationale
=========
Problem
-------
Various words have been used to gneration a new name for an
existing word. This required when porting code and when
generating application wordlists that contain a reference
to an existing word, e.g. when providing limited access
to Forth system kernel words.
Especially with native code compiling Forth systems, these
words have not provided full access to the required behaviour
which requires carnal knowledge of the underlying system, which
is one reason why SYNONYM should be standardised.
Current practice
----------------
The proposed form SYNONYM has been in use at MPE with cross
compilers and VFX Forth since 1998.
Solution
--------
Although many people have objected to parsing words, parsing
permits the host system the most flexibility in implementation
and is thus the preferred solution.
The syntax is:
SYNONYM <newname> <oldname>
where <newname> will behave identically to <oldname>.
Note that <newname> may be the same as <oldname>.
Proposal
========
10.6.2.xxxx SYNONYM
synonym FACILITY EXT
( "<spaces>newname" "<spaces>oldname" -- )
For both strings kip leading space delimiters. Parse name
delimited by a space. Create a new word newname whose
execution behaviour is identical to that of the existing word
oldname. Newname may be the same as oldname.
Ambiguous conditions:
The word newname is parsed by ' or ['] or POSTPONE.
oldname is not found.
Labelling
=========
TBD
Reference Implementation
========================
The implementation of SYNONYM requires carnal knowledge of the host
implementation, which is one reason why it should be standardised.
The implementation below is imperfect and specific to VFX Forth.
: Synonym \ <"new-name"> <"curdef"> --
\ *G 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
;
Test Cases
==========
TBD
--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads
Win32Forth already supports SYNONYM with the same syntax.
George Hubert
ALIAS is used for the same purpose
' <oldname> ALIAS NEWNAME
Its syntax is similar to IS.
My personal vote is for ALIAS
> Especially with native code compiling Forth systems, these
> words have not provided full access to the required behaviour
> which requires carnal knowledge of the underlying system, which
> is one reason why SYNONYM should be standardised.
....
> Ambiguous conditions:
> The word newname is parsed by ' or ['] or POSTPONE.
> oldname is not found.
I see no particular reason not to standardise this just as you say.
It's already reasonably common practice.
As a side issue, what behavior will a portable SYNONYM written in
standard Forth fail at, that doesn't involve ' or ['] or POSTPONE ? I
haven't found anything quickly.
This is as close as I came:
SYNONYM MY-DUP DUP
SYNONYM YOUR-DUP MY-DUP
A portable SYNONYM would probably use ' or ['] or POSTPONE on MY-DUP
here and fit the ambiguous condition, but a primitive SYNONYM wouldn't
have to.
I've been using this for years. Seems it is older than SYNONYM.
--
Coos
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
It breaks on some systems (and they exist) that cannot get from
the xt of a word to enough needed information to create the new
word. The point of SYNONYM is that it can be as carnal as necessary.
Stephen
I ask from ignorance but I don't think if is necessary,
I have only 1 year of forth programing..and 25 of others..
Not so fast :)
I wonder how many missed the part in the spec about making
aliases with the same name!
A conforming SYNONYM should be able to handle this:
\ Test SYNONYM ability to make alias with same name
CR
FORTH ALSO DEFINITIONS
: TEST ." hello " ;
VOCABULARY NEWVOC
NEWVOC DEFINITIONS
SYNONYM TEST TEST ( make alias in new vocab )
CR .( now testing alias ) CR
NEWVOC TEST
You're right; Win32Forth fails this test due to a timing issue creating
the dictionary entry. At the point where SYNONYM is executed, the ORDER
is
order
Context: NEWVOC FORTH FORTH ROOT
Current: NEWVOC ok
TEST is being defined, then searched for, rather than searched for then
defined; so it finds itself rather than the TEST in the FORTH
vocabulary. WIll be corrected.
--
Regards
Alex McDonald
How slow do you want it. -;)
> I wonder how many missed the part in the spec about making
> aliases with the same name!
>
Not me I saw it.
> A conforming SYNONYM should be able to handle this:
>
> \ Test SYNONYM ability to make alias with same name
> CR
> FORTH ALSO DEFINITIONS
> : TEST ." hello " ;
> VOCABULARY NEWVOC
> NEWVOC DEFINITIONS
> SYNONYM TEST TEST ( make alias in new vocab )
> CR .( now testing alias ) CR
> NEWVOC TEST
Win32Forth supports that. I've used both SYNONYM and ALIAS (which
always makes the new word non-immediate irrespective of the immediacy
of the original) to have the same word in diffrent vocabularies many a
time. It's even used in the system for putting FORTH FORTH-WORDLIST and
SET-ORDER in the ROOT vocabulary (the one that's always available after
ONLY) as well as the FORTH vocabulary, so I know it works.
George Hubert
Are you sure? I've just run it under 6.11.07 and it fails.
--
Regards
Alex McDonald
All it needs is to hide the new word until after the second word is
looked up, which has the added advantage that if old-word isn't found
then new-word is hidden (similar to an incomplete : definition).
George Hubert
You're right (although the latest V6.11.09 from the cvs now works
correctly). It's ALIAS (where the xt is passed in) that worked whatever
the search order; SYNONYM requires the voc of old word to be earlier in
the search-order than the current voc. I couldn't run Ed's test for the
original post (or any other) since it hadn't been posted at the time.
V6.10 will also be modified to match; it just requires HIDE and REVEAL.
>
> --
> Regards
> Alex McDonald
George Hubert
For a word "with default compilation behavior" it's easy.
: SYNONYM
:
BL WORD FIND DROP COMPILE,
POSTPONE ; ;
You wind up with a new word that calls the old word. Standard programs
won't do R> DROP etc so they can't tell the difference between doing
one call and one return versus two calls and two returns. It ought to
just work.
But when you try to get synonyms for words that are active at compile
time then you run into all the problems Anton Ertl pointed out for
state-smartness etc. You need two behaviors that will each happen at
precisely the right times and not at the wrong times, and there's no
way to be sure to get those behaviors with all combinations of
compilation, execution, POSTPONE, EXECUTE, and EVALUATE .
But Anton published a portable solution to that problem, where each
word gets two execution tokens and the system is instructed (in a
portable way) which of them to use. And it seems to me that if you use
Anton's system, you should be able to extend it simply for synonyms.
You can easily get the two xt's for the old word, and you can construct
the new word with them. So SYNONYM should be as portable as Anton's
method, for that particular set of problems.
What other portability problems are there?
Why not;
: SYNONYM
:
BL WORD FIND 1 = IF IMMEDIATE THEN COMPILE,
POSTPONE ; ;
which takes care of whether the word is IMMEDIATE as well, although
neither version deals with the case of oldword not being found. It
wouldn't work correctly with separate intepret and compile xts though.
> You wind up with a new word that calls the old word. Standard programs
> won't do R> DROP etc so they can't tell the difference between doing
> one call and one return versus two calls and two returns. It ought to
> just work.
>
Somebody will want a synonym for R> >R for some obscure reason -;)
> But when you try to get synonyms for words that are active at compile
> time then you run into all the problems Anton Ertl pointed out for
> state-smartness etc. You need two behaviors that will each happen at
> precisely the right times and not at the wrong times, and there's no
> way to be sure to get those behaviors with all combinations of
> compilation, execution, POSTPONE, EXECUTE, and EVALUATE .
>
> But Anton published a portable solution to that problem, where each
> word gets two execution tokens and the system is instructed (in a
> portable way) which of them to use. And it seems to me that if you use
> Anton's system, you should be able to extend it simply for synonyms.
> You can easily get the two xt's for the old word, and you can construct
> the new word with them. So SYNONYM should be as portable as Anton's
> method, for that particular set of problems.
>
Depending on how dual xts are implemented it's possible to make SYNONYM
just point the name of to the same address as oldword points to, though
this means the 2 words behave exactly the same forevermore (i.e. if you
supply an optimised compile to newword then compiling oldword does the
same optimising from then on as well).
> What other portability problems are there?
Probably many. Separate wordlists for compilation words springs to
mind. I don't think a portable version for all systems is possible
though ones can be written for common implementation strategies; IMO
that's probably why it needs standardising.
George Hubert
I've just implemented this as it seems a useful addition, although I
would have preferred SYNONYM <oldname> <newname> as it seems more
natural to find the old one before creating the new name but no matter.
I have the following questions, (nit picking I know but it is for a
standard):
1. Your reference implementation creates a new immediate word.
Therefore FIND <newname> will return a different result to FIND
<oldname> both due to a different xt (probably) and because <oldname>
may not be immediate. Does this matter?
2. If an implementation is an exact synonym i.e. FIND returns the same
xt and <newname> follows <oldname> immediacy as well as behaving
exactly the same, does SYNONYM count as a defining word in the terms of
the ANS standard e.g. if the old word abc is not immediate will
SYNONYM xyz abc IMMEDIATE
make xyz or the previous definition immediate, or should it make both
xyz and abc immediate or is it an ambiguous condition. I think making
only xyz immediate is the best.
3. Just thought of this as I was about to post this message. With your
implementation would the following work?
SYNONYM ENDIF THEN
For the record my implementation creates an exact synonym so ' ['] and
POSTPONE will all work with <newname> which I think is better than
making that an ambiguous condition.
Gerry
> > For a word "with default compilation behavior" it's easy.
> > : SYNONYM
> > :
> > BL WORD FIND DROP COMPILE,
> > POSTPONE ; ;
> Why not;
> : SYNONYM
> :
> BL WORD FIND 1 = IF IMMEDIATE THEN COMPILE,
> POSTPONE ; ;
I dunno. That might work. There were a lot of traps and I haven't
thought about it for awhile, maybe some of them would bite you on this.
To be on the safe side it might make sense to make it immediate after
you've postponed ; but I've never noticed an implementation that won't
make an incomplete definition immediate.
> which takes care of whether the word is IMMEDIATE as well, although
> neither version deals with the case of oldword not being found. It
> wouldn't work correctly with separate intepret and compile xts though.
Yes. Two incompatible systems. One has tradition and the other works
better.
> Somebody will want a synonym for R> >R for some obscure reason -;)
Oops! You got me there. So the simple implementation fails even when R>
>R have no special compilation behavior. So it fails.
> Depending on how dual xts are implemented it's possible to make SYNONYM
> just point the name of to the same address as oldword points to, though
> this means the 2 words behave exactly the same forevermore (i.e. if you
> supply an optimised compile to newword then compiling oldword does the
> same optimising from then on as well).
Yes.
> > What other portability problems are there?
> Probably many. Separate wordlists for compilation words springs to
> mind. I don't think a portable version for all systems is possible
> though ones can be written for common implementation strategies; IMO
> that's probably why it needs standardising.
Have you figured out how to do separate wordlists for compilation words
in a standard system? When I tried that it turned into a briar patch.
Define a new word with the old name that isn't immediate, and watch the
old version get found during compilation. Etc. Getting the standard
behaviors seemed to beg for a synonym in whichever wordset you aren't
defining in at the moment. Those systems are designed to work different
from standard, and it wrenches their soul to try to make them conform.
Anyway, if Anton's dual-wordlist approach can be implemented on any
standard system using only standard words, then it looks to me like
adding SYNONYM to it ought to be trivial. So SYNONYM should be very
widely portable.
I want to remark that it is important to standardize words
that *cannot* be portably implemented, or not efficiently.
It is much less important to standardize words that can
be portably implemented, as they can always be made
part of the application.
--
Groetjes Albert
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
alb...@spenarnc.xs4all.nl http://home.hccnet.nl/a.w.m.van.der.horst
Well, for the case of SYNONYM in the latest dual-xt version of W32F
based on Anton's suggestions (see here
http://www.complang.tuwien.ac.at/forth/header-ideas.html), it will be
important. To ensure the right behaviour with dual xts for words that
have non-standard compilation semantics, the synonym must either be an
immediate word that always executes the compile token of the underlying
word, or a complete copy of the dictionary entry. I can't think of a
portable ANS way to implement SYNONYM that would support such systems.
As an aside, this version of W32F passes the postpone test
(http://www.complang.tuwien.ac.at/forth/postponetest.fs).
--
Regards
Alex McDonald
>1. Your reference implementation creates a new immediate word.
>Therefore FIND <newname> will return a different result to FIND
><oldname> both due to a different xt (probably) and because <oldname>
>may not be immediate. Does this matter?
No.
>2. If an implementation is an exact synonym i.e. FIND returns the same
>xt and <newname> follows <oldname> immediacy as well as behaving
>exactly the same, does SYNONYM count as a defining word in the terms of
>the ANS standard e.g. if the old word abc is not immediate will
>
> SYNONYM xyz abc IMMEDIATE
>
>make xyz or the previous definition immediate, or should it make both
>xyz and abc immediate or is it an ambiguous condition. I think making
>only xyz immediate is the best.
IMMEDIATE affects the last dictionary entry which is XYZ.
I have already made this an ambiguous condition.
>3. Just thought of this as I was about to post this message. With your
>implementation would the following work?
> SYNONYM ENDIF THEN
Yes.
Stephen
> delimited by a space. Create a new word newname whose
>execution behaviour is identical to that of the existing word
>oldname.
"execution behaviour" is not a standard term. If you mean "execution
semantics", then SYNONYM is no more powerful than ALIAS. If you want
to make SYNONYM more powerful than ALIAS, how about the following
specification:
... Create a definition for newname with the semantics defined below:
newname interpretation: ( i*x -- j*x )
Perform the interpretation semantics of oldname
newname compilation: ( i*x -- j*x )
Perform the compilation semantics of oldname
> Newname may be the same as oldname.
That's true by default, so leave it away here; you may want to point
it out in an informal part.
>Ambiguous conditions:
> The word newname is parsed by ' or ['] or POSTPONE.
No! If you can tick or POSTONE oldname, you should also be able to do
this to newname, or it won't be a synonym. Moreover, having words
that cannot be ticked or postponed in the standard is bad enough, we
don't need to add defining words for such monstrosities; I would
consider a language that had such defining words to be not Forth.
Also, I don't see a technical reason for such a restriction
(especially if you don't make [COMPILE] newword ambiguous).
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2006: http://www.complang.tuwien.ac.at/anton/euroforth2006/
Actually my implementation has bugs, but since nobody seemed
interested, fixing them never got to the top of my agenda.
> And it seems to me that if you use
>Anton's system, you should be able to extend it simply for synonyms.
>
>You can easily get the two xt's for the old word,
Does not seems so easy to me.
Hmm, the xt for the compilation semantics could be constructed like
this:
:noname POSTPONE oldname ;
The interpretation semantics might be gotten by just ticking the word
(and maybe CATCHING any errors). But for words with undefined
interpretation semantics, one might not get what one wants.
Still, it looks like it is possible to do it (apart from the return
stack words, as someone else mentioned).
|6.1.1550 ... For a given string, the values returned by FIND while
|compiling may differ from those returned while not compiling.
In any case, this version of SYNONYM would not work as it should when
defining a synonym for S" on Gforth.
>It
>wouldn't work correctly with separate intepret and compile xts though.
Yes, that's it.
I think the right approach is to have a wordlist for the
interpretation/execution semantics of standard words, a wordlist for
the compilation semantics of standard words, and a wordlist for
user-defined words. In interpretation state, you search user, then
interpretation; in compilation state, you search user, then
compilation, then interpretation.
Of course, this scheme becomes complicated once you want to implement
the search-order wordset, so complicated that it isn't worth doing.
I find it simpler to reserve 2 extra bits in each header, an
interpretation bit, a compilation bit, in addition to the traditional
precedence (i.e. immediate) bit.
A normal word has interpretation=1 compilation=1 precedence=0
A normal immediate word has i=1 c=1 p=0
A compile-only non-immediate word has i=0 c=1 p=0
A directive (i.e. compile-only immediate) word has i=0 c=1 p=1
An interpret-only word has i=1 c=0 p=0
Cheers,
Mark W. Humphries
Manila, Philippines
> >You can easily get the two xt's for the old word,
> Does not seems so easy to me.
I may have misunderstood, or I may be asking too much. I thought, you
came up with an approach that stored two xt's for each word, and an
interpreter/compiler that used those appropriately, and the code which
does that *could* be done correctly and portably. Once a system has
that code ported to it, SYNONYM could use the internals of your code to
copy the two xts to the new word. Your interpreter/compiler would then
treat both words identically.
> Hmm, the xt for the compilation semantics could be constructed like
> this:
> :noname POSTPONE oldname ;
> The interpretation semantics might be gotten by just ticking the word
> (and maybe CATCHING any errors). But for words with undefined
> interpretation semantics, one might not get what one wants.
Yes. But interpreting those words is ambiguous anyway.
> Still, it looks like it is possible to do it (apart from the return
> stack words, as someone else mentioned).
If return stack words are immediate then it's no problem. The copy is
immediate, at compile time it calls the old word which performs its
compile magic and the runtime result is the same. If return stack words
are not immediate then it's no problem. The compiler gets the xt of the
old word and compiles it.
Without the special compiler we're left with a state-smart word, that
in some cases is supposed to give the same result as a non-state-smart
word.
So the only way left I can see is to make the compiler/interpreter do
the work. If every word has two xt's and the compiler chooses which to
use, you can give the same xt's to the synonym that the old word has.
It will behave exactly like the old word.
It isn't easy to do it with wordlists. Say we have 3 wordlists, COMPILE
INTERPRET and FORTH . First we search FORTH . Then we search COMPILE or
INTERPRET and swap the order of those two if we're compiling instead of
interpreting. We avoid the state-smart traps by compiling synonyms into
COMPILE and INTERPRET .
: FOO dosomething ;
SYNONYM FOO BAR
We'll always find the old FOO instead of the new foo. So that doesn't
work.
Say we have only two wordlists, COMPILE and INTERPRET .
: FOO dosomething ; immediate
: FOO somethingelse ;
Now we'll get the old FOO when we compile unless we make two
definitions for each word. That's wasteful but it can be done, the
compiler must automatically define
: FOO [ ' FOO ] LITERAL COMPILE, ;
every time you make a word with standard compile behavior.
If you want multiple wordlists you'll need two real wordlists for each
official wordlist, you'll have an interpret version and a compile
version. And then I think SYNONYM works for nonimmediate >R .
SYNONYM PUSH >R
The compile version will go
: PUSH [ ' >R ] literal compile, ;
so it will do exactly the same thing as >R at compile time.
I rejected this approach the last time I thought about it because I was
using a Forth that fit into 8K and it seemed like unacceptable bloat to
double the number of words. But it might work. Of course if you try to
implement it portably, it will only work on Forths that allow multiple
wordlists, and Forths that allow only 8 wordlists will only have 4
wordlists available to users.
And you'll need a top-level definition something like:
: COLD
BEGIN ['] my-interpreter CATCH handle-exceptions AGAIN ;
And any throw it can't handle itself will dump you back to the original
system.
I think the central problem here comes because the original Forth
interpreter was too simple. One state. You execute or
compile-or-execute, then you check if it's a number. Everything else
could be done by the words themselves. And we wound up with endless
complication in the words themselves. As I understand it, with
ColorForth Chuck has moved on to having 8 or so special tokens that
affect state, and everything else just does one thing. No immediate
words except those tokens, the token says whether to execute or
compile. That's [ ] and you don't compile those into other words. A
token to say it's a number. A token to say it's a character, like CHAR
and [CHAR] . A token to say it's an execution token like ' and ['] .
Chuck doesn't need words that second-guess him about how to handle
source code, he knows what he wants to happen and he can just tell it
to happen.
I think code written that way could be translated into standard Forth
fairly easily. The translator could look at each word, note its default
standard behavior, and see what it had to do to provide it. [ ] CHAR
LITERAL etc. So if you choose to write that way, your code should be
quite portable. And you won't have to worry about how to extend the
standard to allow many forths to all do something complicated and make
it work.
It occurs to me that given a good editor, one possible way to implement
SYNONYM would be to have it do a global search and replace. But only
forward. It doesn't quite work.
Another approach that almost works is
: SYNONYM
:
POSTPONE S"
POSTPONE EVALUATE
POSTPONE ;
IMMEDIATE ;
But that fails for parsing words. There's always something. Traditional
Forth is a brittle about this stuff, too coadapted, too many
interdependencies making it hard to change one thing without breaking
something else.
> how about the following specification:
>
>... Create a definition for newname with the semantics defined below:
>
> newname interpretation: ( i*x -- j*x )
> Perform the interpretation semantics of oldname
>
> newname compilation: ( i*x -- j*x )
> Perform the compilation semantics of oldname
Accepted. In the current draft.
>> Newname may be the same as oldname.
>
>That's true by default, so leave it away here; you may want to point
>it out in an informal part.
The statement helps to reduce the number of incorrect implementations!
>>Ambiguous conditions:
>> The word newname is parsed by ' or ['] or POSTPONE.
>
>No! If you can tick or POSTONE oldname, you should also be able to do
>this to newname, or it won't be a synonym. Moreover, having words
>that cannot be ticked or postponed in the standard is bad enough,
{snipped]
The more I explore the implications, the more I gree with you.
But (and it's a big but), there are a huge number of systems out
there that do not comply, and fail under pathological conditions
that "normal" users do not encounter. This includes some MPE
systems.
I would much prefer to mark bad behaviour in this area as being
subject to restriction in the next round. The reason is to
encourage rapid uptake of Forth200x.
It should also do that if it is in an informal part. In particular,
if you make a test case for this.
>>>Ambiguous conditions:
>>> The word newname is parsed by ' or ['] or POSTPONE.
>>
>>No! If you can tick or POSTONE oldname, you should also be able to do
>>this to newname, or it won't be a synonym. Moreover, having words
>>that cannot be ticked or postponed in the standard is bad enough,
>{snipped]
>
>The more I explore the implications, the more I gree with you.
>But (and it's a big but), there are a huge number of systems out
>there that do not comply, and fail under pathological conditions
>that "normal" users do not encounter. This includes some MPE
>systems.
Can you give an example of such pathological conditions?
>I would much prefer to mark bad behaviour in this area as being
>subject to restriction in the next round.
This will never happen. If a system implementor does not go for
implementing SYNONYM properly the first time, they will resist such a
change later. At that time, any change in implementation has the risk
of breaking existing programs.
>The reason is to
>encourage rapid uptake of Forth200x.
Since SYNONYM is an optional part, they can take up the rest of
Forth200x without implementing SYNONYM. So I don't see that
specifying a proper SYNONYM would slow down the uptake of Forth200x,
or that specifying a broken SYNONYM would speed up the uptake of
Forth200x.
> >> Newname may be the same as oldname.
> >That's true by default, so leave it away here; you may want to point
> >it out in an informal part.
> The statement helps to reduce the number of incorrect implementations!
Good point!
> >>Ambiguous conditions:
> >> The word newname is parsed by ' or ['] or POSTPONE.
> >No!
> The more I explore the implications, the more I gree with you.
> But (and it's a big but), there are a huge number of systems out
> there that do not comply, and fail under pathological conditions
> that "normal" users do not encounter. This includes some MPE
> systems.
It would be possible to go ahead and declare a correct standard, and
let the noncomplying systems document their small degree of
noncompliance.
A minor problem in the Facilities Extension wordset shouldn't be too
much of a problem for implementors who want to call their systems
standard. And if they don't care about fixing SYNONYM now, why would
they care more later?
Instead of concentrating on how to implement SYNONYM
I would like to see a careful unambiguous statement about
how it supposed to work.
By the way I hate this word. This would be the first definition
in the standard where parsing is done beyond the next word.
Groetjes Albert
--
Consider what would happen if the arguments were reversed.
I'll call it SYNONYM2 -
SYNONYM2 <oldname> <newname>
With this syntax, there's no temporal issue and hiding/revealing
is not necessary. If <oldname> isn't found then nothing is
created in the dictionary.
SYNONYM takes more effort to implement on systems where
xt must be known at head creation. In contrast, SYNONYM2
has all the information available at create time.
IMO, for alias creation the syntax <oldname> <newname>
is technically superior.
I also have concerns with the name. Given its frequency
SYNONYM is far too long to type (and a horror to spell :)
Can we do better?
-------------
"Common practice" is not necessarily "best practice".
As I recall it from the beginning of this thread, the argument against
ALIAS
' oldname ALIAS newname
was that some systems find it hard to support finding the oldname word
header from the xt, and so wouldn't be able to find all the details it might
need to properly alias it. Is that reason enough to introduce this
double-forward-parsing SYNONYM monstrostity that *still* can't guarantee
that newname will share all the characteristics of oldname?
ALIAS is already demonstrably common-usage, and ideally will create an exact
duplicate of oldname, flags and semantics and all. If a given Forth can't
do that, so be it. If so few Forths can do that that it doesn't warrant
being discussed as a new standard, so be it. Let's not add a new word that
is simultaneously ugly, short on functionality, and riddled with ambiguous
conditions.
--
Neal Bridges
http://quartus.net Home of Quartus Forth for the Palm OS!
> Instead of concentrating on how to implement SYNONYM
> I would like to see a careful unambiguous statement about
> how it supposed to work.
What it's supposed to do, is let you add a second name whose behavior
is exactly like an existing definition. Or close enough that the
differences don't cause trouble.
This aids code portability. It doesn't so much help port standard code
among standard systems. It's potentially a big help for porting
standard code to nonstandard systems, or nonstandard code to standard
systems.
Say you want to port a big body of code to a new system, and it turns
out that one of them uses THEN and the other uses ENDIF . One solution
is to take a text editor and do a global replace on every file you want
to port. That might be the best way, although you may get a few
comments like "First we do x, and ENDIF we do y".
Another method is to use whatever programming tools are available from
the Forth you're porting to, and find the definition of ENDIF , and
make THEN with exactly the same definition. That's an inconvenience but
not so very hard. But SYNONYM lets you do it without knowing anything
about how the old word works.
It looks to me like the main value for SYNONYM is that it lets you make
things just work. You can write code that you can hope will port
effortlessly to many systems. If there's a Forth expert for each system
who can spare the time to track down all the problems, then SYNONYM
isn't that valuable. All SYNONYM gives you is the chance to make things
work without having to know all the details.
If you can define it portably, there isn't nearly as much need to
standardise it. You can put it into a library and anybody who wants to
use it can just compile the reference version. Or if they want to
improve performance they can come up with a version that's better for
their system, and if it passes the test suite it's probably OK.
You might argue that there's no need for SYNONYM . But all the people
who discuss the details of how to write the standards document for it,
think it's worth doing. If you think it isn't worth doing then make the
argument.
> By the way I hate this word. This would be the first definition
> in the standard where parsing is done beyond the next word.
\ parses to the end of the line. (( parses until it reaches a )) or end
of file, although (( isn't defined in the standard, it's just written
using standard code. There are probably others.
It needn't be such a big deal about the order of the words. Do
>IN @ BL WORD >IN @ BL WORD
and you can back up to either word and parse it whenever you want.It's
just a little extra stack juggling. I prefer the old name first and
then the new name, but there's historical pecedent the other way. And
it doens't look like a lot of difficulty to me, now.
"Given its frequency?" I have counted occurrences of ALIAS, AKA and
SYNONYM in all the files (over 7,000 in total) I have for SwiftForth
(80), VFX (5), Win32Forth (47), gForth (13) and iForth (0). (There
are more references, but that's in documentation and defining the
words themselves.)
In many cases I saw, it seems that doing : bar ... ; : foo bar ;
would be perfectly adequate as bar has no special characteristics
and foo is not time-critical.
I'm not against standardizing this word; it is obviously in use
by many Forths with conflicting names. But I am curious what's so
fascinating about this word?
I will always need to look up the documentation for SYNONYM, is
it <oldword> <newword> or the reverse?
Clearer would be :SYNONYM <newname> <oldname> SYNONYM; or
:SYNONYM <newname> <oldname> ;
-marcel
> Say you want to port a big body of code to a new system, and it turns
> out that one of them uses THEN and the other uses ENDIF . One solution
> is to take a text editor and do a global replace on every file you want
> to port. That might be the best way, although you may get a few
> comments like "First we do x, and ENDIF we do y".
Unless that code does : BAR S" ENDIF" EVALUATE ; IMMEDIATE
or ...
If I use SEE on a word using a SYNONYM, which name is shown?
-marcel
Such an ALIAS has a conflict with Gforth's ALIAS, which just produces
a word that has the execution/interpretation semantics specified by
the xt, but default compilation semantics. In particular, it is not
immediate, whether the ticked word is immediate or not.
So a least common denominator would make the compilation semantics of
an ALIAS undefined, unless the original had default cmpilation
semantics (then it has default compilation semantics), or unless
IMMEDIATE is applied (then it is immediate).
With such an ALIAS, we cannot do as easily what SYNONYM can do, but we
can combine it with other techniques to achieve the same
functionality:
For a word with default compilation semantics, use
' R@ alias my-r@
For an immediate word, use
' ( alias my-* immediate
For a word with non-default compilation semantics und undefined
interpretation semantics, use:
: endif POSTPONE then ; immediate
For a word with defined interpretation semantics and non-default,
non-immediate compilation semantics, you could define it in a
STATE-smart way (and it will fail when the original will also fail on
some system), or you could use the refined technique discussed in
http://www.complang.tuwien.ac.at/forth/dpans-html/comment-semantics.html;
for simplicity, here's the state-smart variant:
: my-s"
state @ if
postpone S"
else
['] S" execute
then ; immediate
So what SYNONYM offers above ALIAS is the convenience of not having to
make this case analysis.
Hmm:
[~/gforth:52244] find . -name \*.fs| xargs grep -i alias|wc -l
218
Some of these are in comments, but most are actual uses.
>I will always need to look up the documentation for SYNONYM, is
>it <oldword> <newword> or the reverse?
I also see this problem.
>Clearer would be :SYNONYM <newname> <oldname> SYNONYM; or
>:SYNONYM <newname> <oldname> ;
Yes; or a self-documenting name that contains NEW and OLD in the order
needed by the syntax. E.g., in the simplest case:
NEW-OLD newname oldname
What about NEW-NAME for the version of ALIAS with the function
of SYNONYM?
' oldname NEW-NAME newname
-- David
An xt does not contain enough information for performing the function
of SYNONYM.
Conversely, you can do things with ALIAS that you cannot do with
SYNONYM: give a name to an anonymous word:
:noname ... ; alias foo
Or if you have access to the xt, but not easily to the name. E.g.:
' deferred-word defer@ alias bar
If we wanted to have a word with the functionality of SYNONYM where we
pass the oldname on the stack, the best approach would be to introduce
a name token (implemented as NFA on most systems), and pass that.
E.g., something like:
s" oldname" FIND-NAME ( nt ) NEW-NAME newname
But I guess that this proposal would then have to wait until we had
one for name tokens and their related words.
I thought you might say that! :-)
-- David
Yes.
> Once a system has
>that code ported to it, SYNONYM could use the internals of your code to
>copy the two xts to the new word.
Yes, but then SYNONYM would work only for oldwords defined in that
way. But for, e.g., the words originally in the system, getting the
necessary xts could be a problem.
>> The interpretation semantics might be gotten by just ticking the word
>> (and maybe CATCHING any errors). But for words with undefined
>> interpretation semantics, one might not get what one wants.
>
>Yes. But interpreting those words is ambiguous anyway.
Yes, so as long as you don't want to copy the system-defined
interpretation semantics, you should be all right.
>If return stack words
>are not immediate then it's no problem. The compiler gets the xt of the
>old word and compiles it.
Sorry, you lost me here.
>So the only way left I can see is to make the compiler/interpreter do
>the work. If every word has two xt's and the compiler chooses which to
>use, you can give the same xt's to the synonym that the old word has.
>It will behave exactly like the old word.
Yes, but the original words in the system don't have two xts. And my
program uses the definition only for words that are likely to be
implemented in a STATE-smart way in the system.
>It isn't easy to do it with wordlists.
No, the wordlists approach is no good for letting users define
combined words and similar things. Actually, the fact that no
standard systems have appeared that use it indicates that there are
better ways for implementing standard systems.
>It occurs to me that given a good editor, one possible way to implement
>SYNONYM would be to have it do a global search and replace. But only
>forward. It doesn't quite work.
One significant use of SYNONYM/ALIAS is to put the same name in
several wordlists.
> If we wanted to have a word with the functionality of SYNONYM where we
> pass the oldname on the stack, the best approach would be to introduce
> a name token (implemented as NFA on most systems), and pass that.
> E.g., something like:
>
> s" oldname" FIND-NAME ( nt ) NEW-NAME newname
>
> But I guess that this proposal would then have to wait until we had
> one for name tokens and their related words.
Which would appear to be more important than something that is
implementable with
vocabulary vnew
also vnew definitions
: newname oldname ;
previous definitions
in any ANS system; unless there's something about SYNONYM that I'm
missing that makes it only implementable with carnal knowledge..
--
Regards
Alex McDonald
> If I use SEE on a word using a SYNONYM, which name is shown?
I don't care.
Yes on my system it needs to do an exact duplicate of the oldword.
The only difference is the name. The new name points to the same
executable code.
It is mainly used in the metacompiler on words with special compilation
actions.
My system has 2 xts for every word
With a set of words to access the header information it is easy to
define
: synonym ( -- ) \ use as synonym new old makes a twin of old and
names it new
header \ create
new header
parse-word findheader found? \ find old header
reveal
\ make new header
findable
dup >xtr @ last-head @ >xtr ! \ copy the
execution addr
dup ht>len w@ last-head @ ht>len w! \ copy len of execution
code
dup ht>lenc c@ last-head @ ht>lenc c! \ copy len of compilation
code
dup ht>flag c@ last-head @ ht>flag c! \ copy flags
>xtc @ set-xtc ; \ copy the
compilation addr
regards
peter
>
> --
> Regards
> Alex McDonald
> > Once a system has
> >that code ported to it, SYNONYM could use the internals of your code to
> >copy the two xts to the new word.
> Yes, but then SYNONYM would work only for oldwords defined in that
> way. But for, e.g., the words originally in the system, getting the
> necessary xts could be a problem.
It should be possible to redefine every oldword (or maybe just all the
standard words your code will use), using the methods you described
above. For compile-only words you might not get the interpret behavior
you want (if you get an error you can give them an xt that will
announce an error and throw). You *might* get great interpret behavior
you don't expect. interpreted DO loops etc, that are not standard
partly because we can't expect legacy systems to implement them.
You don't know what you'd get, but you don't know what you'll get if
you try to intepret those oldwords either so it's only reasonable the
newwords would be the same way.
> >If return stack words
> >are not immediate then it's no problem. The compiler gets the xt of the
> >old word and compiles it.
> Sorry, you lost me here.
>R etc can be implemented as compiler words that do something special at compile time. Or they can be simply nonimmediate words that violate the standard return stack conventions in a system-dependent way to get their result. They're listed as compiler-only words because their behavior when typed in from the keyboard in interpret state is not defined. (I've used Forth systems where you can have 5 >R in the input stream and it just works, and doesn't crash provided you do R> before the end of the line, or the end of the block. But the standard makes no guarantee whatsoever.)
So when >R is a word with default compilation behavior (but nondefault
interpret behavior, its *execute* behavior is what's defined), then a
synonym will work provided that it compiles the execution token of >R .
A synonym that simply has default compilation behavior won't work
because its own execution token will be compiled instead of >R's
execution token. But anything you do that gets it to compile >R's
execution token will work for a synonym of >R .
But if we replace a default-compilation-behavior >R with a
nondefault-compilation-behavior synonym, then what happens if we get
the xt of the synonym and execute it? Well, this is turning kind of
murky, what happens if you get the xt of >R and execute that? I don't
think it's guaranteed to have an xt you can use. I'm not clear whether
there's a problem here.
You could use things under-the-hood to implement SYNONYM nonportably.
Like, if >R calls a primitive, it's no big deal to get synonyms to call
the same primitive. Problem solved, nonportably.
If you can get the compiler to somehow look at MY>R and compile the xt
for >R without MY>R having to be immediate, then that should solve it
too. And I thought your dual-wordlist system would do that.
> One significant use of SYNONYM/ALIAS is to put the same name in
> several wordlists.
I didn't think of that!
If your wordlists are made with hash tables, is there any reason the
same word can't go into multiple wordlists? Copy your hash wherever you
like, the first one that gets searched and finds it will report back.
But that can't work for wordlists implemented as linked lists. You can
link to a word as many times as you like, but the word itself will only
link to one continuing list.
So we must restrict what we do with modern systems so we can cater to
old or minimal systems -- and the minimal ones probably will have
little need for SYNONYM anyway.