Proposal: [311] New words: latest-name and latest-name-in
This page is dedicated to discussing this specific proposal
ContributeContributions
ruv
[311] New words: latest-name and latest-name-inProposal2023-10-23 01:13:22
Author
Ruv
Change Log
- 2023-10-22 Initial revision
Problem
In some applications, mainly in libraries and extensions, the capability to obtain the most recently added definition is very useful and demanded.
For example, if we are creating a library for decoration, tracing, support for OOP, simple DSLs (e.g., to describe Final State Machines), etc — it is always useful to have an accessor to the recent definition, instead of redefining a lot of words to define such an access method yourself, or juggling with the input buffer and search.
However, many Forth systems have such internal methods to access the recently added word. Among them: latest ( -- nt|0 )
, last @ ( -- nt|0 )
, latestxt ( -- xt|0 )
, etc.
And additionally, there has been much discussions regarding standardization of such a method in recent decades. For example, Elizabeth D. Rather wrote on 2011-12-09 in comp.lang.forth
:
AFAIK most if not all Forths have some method for knowing the latest definition, it's kinda necessary. The problem is, that they all do it differently (at different times, in different forms, etc.), which is why it hasn't been possible to standardize it.
Although it's a system necessity, I haven't found this of much value in application programming.
Elizabeth D. Rather
It's true: depending on the system, an internal method can return the recent word regardless of the compilation word list, or depending on the compilation word list, a completed definition, or not yet completed definition, also unnamed definition, or only named definition, etc.
Nevertheless, the author convinced that we can standardize a consistent method that solves the problem.
Solution
Let's introduce the following words:
LATEST-NAME-IN ( wid -- nt|0 )
LATEST-NAME ( -- nt )
The former word returns the name token for the definition name that was placed most recently into given word list, or zero if this word list is empty.
The latter word returns the name token for the definition name that was placed most recently into the compilation word list, or throws an exception if such a definition is absent.
It seems, the best place for these words is the section 15.6.2 Programming-Tools extension words), where TRAVERSE-WORDLIST
is also placed.
Rationale
Connection with word lists
By considering definitions in the frame of a word list only, we solve several problems, namely:
A word list contains only completed definitions (see the accepted proposal #153 Traverse-wordlist does not find unnamed/unfinished definitions). This eliminates the question of whether the word of returned nt is finished — yes, it is always finished (completed).
Unnamed definitions are not considered since they are not placed into the compilation word list (regardless of whether the system creates a name token for them, or places them into an internal system-specific word list).
An extension or library can create definitions in its internal word list for internal purposes. And it will not affect the compilation word list or other user-defined word lists. Thus, the user of such library always gets the expected result from
latest-name
(regardless of what words are created by this library for internal purposes on the fly).
Return values
As a matter of practice, almost all the use cases for the word LATEST-NAME
imply that the requested definition exists, and if it doesn't exist, only an error can be reported. So the option to return 0
by this word only burdens users with having to analyze this zero, or redefine this word as:
: latest-name ( -- nt ) latest-name dup 0= -80 and throw ;
If the user needs to handle the case where the compilation word list is empty, they can use the word latest-name-in
as:
get-current latest-name-in dup if ( nt ) ... else ( 0 ) drop ... then
Implementation options
In some plausible Forth systems, the word list structure doesn't contain any information about the definition that was placed into this word list most recently. Such systems might not provide the proposed words, or they are changed to keep the mentioned information in the word list structure. It seems, in most systems the word list structure contains this information.
If a system does not implement The optional Search-Order word set, it might not provide the word LATEST-NAME-IN
.
Naming
The names for these words LATEST-NAME-IN
and LATEST-NAME
are similar to FIND-NAME-IN
and FIND-NAME
. Ditto for stack effects.
Typical use
: STRUCT: ( "name" -- wid.current.old u.offset )
GET-CURRENT VOCABULARY
ALSO LATEST-NAME NAME> EXECUTE DEFINITIONS
0
;
Proposal
Add the following line into the Table 9.1: THROW code assignments:
-80
compilation word list is empty
Add the following sections into 15.6.2 Programming-Tools extension words:
15.6.2.2541 LATEST-NAME-IN
( wid -- nt|0 )
Remove the word list identifier wid from the stack. If this word list is empty, then return 0
, otherwise return the name token nt for the definition that was placed most recently into this word list.
15.6.2.2542 LATEST-NAME
( -- nt )
Return the name token nt for the definition that was placed most recently into the compilation word list, if such definition exists. Otherwise throw exception code -80
.
Reference implementation
In this implementation we assume that wid is an address that contains nt of the most recently placed definition name into the word list wid.
: LATEST-NAME-IN ( wid -- nt|0 ) @ ;
: LATEST-NAME ( -- nt )
GET-CURRENT LATEST-NAME-IN DUP IF EXIT THEN -80 THROW
;