,---------------. | Contributions | `---------------´ ,------------------------------------------ | 2023-10-23 01:13:22 ruv wrote: | proposal - New words: latest-name and latest-name-in | see: https://forth-standard.org/proposals/new-words-latest-name-and-latest-name-in#contribution-311 `------------------------------------------ ## 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](https://groups.google.com/g/comp.lang.forth/c/RsJQVnEQQuw/m/M1PrzPAcE-0J) 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](https://forth-standard.org/standard/tools#subsection.15.6.2)), 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: 1. A word list contains only completed definitions (see the accepted proposal #153 [Traverse-wordlist does not find unnamed/unfinished definitions](https://forth-standard.org/proposals/traverse-wordlist-does-not-find-unnamed-unfinished-definitions?hideDiff#reply-487)). This eliminates the question of whether the word of returned _nt_ is finished — yes, it is always finished (completed). 2. 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). 3. 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](https://forth-standard.org/standard/exception#table:throw): > `-80` compilation word list is empty Add the following sections into [15.6.2 Programming-Tools extension words](https://forth-standard.org/standard/tools#subsection.15.6.2): #### 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 ; ``` ,------------------------------------------ | 2023-10-23 10:04:08 ruv wrote: | testcase - TRAVERSE-WORDLIST must not expose the current definition | see: https://forth-standard.org/standard/tools/TRAVERSE-WORDLIST#contribution-312 `------------------------------------------ `TRAVERSE-WORDLIST` is not allowed to visit the current definition, unfinished or hidden definitions (see also the accepted proposal #153 [Traverse-wordlist does not find unnamed/unfinished definitions](https://forth-standard.org/proposals/traverse-wordlist-does-not-find-unnamed-unfinished-definitions?hideDiff#reply-487)). Some systems place the current definition into the compilation word list and change its header in such a way that this definition cannot be found via `FIND-NAME-IN` or `SEARCH-WORDLIST`. By a mistake, `nt` for this definition can be exposed by `TRAVERSE-WORDLIST`. This test ensured that the current definition is not exposed, and that the correct number of names is placed into the compilation word list. ``` : WORDLIST-LENGTH ( wid -- u ) >R 0 [: DROP 1+ TRUE ;] R> TRAVERSE-WORDLIST ; : L ( -- u ) GET-CURRENT WORDLIST-LENGTH ; T{ L :NONAME [ L ] LITERAL ; EXECUTE L = = -> TRUE }T T{ L : TW1 [ L ] LITERAL ; TW1 OVER = SWAP 1+ L = AND -> TRUE }T ``` ,---------. | Replies | `---------´ ,------------------------------------------ | 2023-09-28 17:51:10 ruv replies: | proposal - NAME>INTERPRET wording | see: https://forth-standard.org/proposals/name-interpret-wording#reply-1110 `------------------------------------------ ## Author Ruv ## Change Log - 2020-02-20 Initial comment for [`NAME>INTERPRET`](https://forth-standard.org/standard/tools/NAMEtoINTERPRET) - 2023-09-14 Make this proposal more formal - 2023-09-19 Add rationale, better wording, fix some typos - 2023-09-21 Add rationale re system-defined semantics, and declare an ambiguous condition - 2023-09-22 Require xt if interpretation semantics for the word are defined by the standard - 2023-09-28 Add a clause re STATE-dependent execution semantics in Problem, add a section re execution of xt meaning in Rationale, better wording and formatting in some places ## Problem 1. It's currently unclear from the specification for [`name>interpret`](https://forth-standard.org/standard/tools/NAMEtoINTERPRET) how to perform the interpretation semantics for the word identified by _nt_ — namely, how to perform the behavior that a Forth system performs when the Forth text interpreter, while in interpretation state, encounters the name of a word identified by this _nt_ (see also Rationale below). 2. The specification for [`name>interpret`](https://forth-standard.org/standard/tools/NAMEtoINTERPRET) says that returned "_xt_ represents the interpretation semantics of the word _nt_". But actually, in some cases a Forth system cannot provide an xt that performs the interpretation semantics for the corresponding word regardless of `STATE`. Particularly, when _nt_ is for a word whose execution semantics depends on STATE, or for a word like `s"` or `to`, if it is implemented as an immediate word. Technically, it is possible to return a correct xt according to the current specification (e.g. via generation of the corresponding definition on the fly), but it can be too burden. 3. A minor problem is that it's not clear what the term **represent** means. According to the language of the standard, xt **identifies** some semantics. ## Rationale ### How to perform interpretation semantics It should be clear from the specification how, having an nt, to perform the very behavior that a Forth system performs when the Forth text interpreter, while in interpretation state, encounters the name of a word identified by this nt. Namely, in the general case, to perform this behavior, must the xt returned from `name>interpret` be executed only in interpretation state, or it may be also executed in compilation state. ### Execution of xt In this proposal, the author assumes that `compile,` is equivalent to `lit, ['] execute compile,`, and therefore "**_xt_ is executed**" means "**the execution semantics identified by _xt_ are performed**" — no matter how — via `execute` directly, or as a part of execution semantics of another definition, in any nesting, when this part is appended by applying `compile,` to this _xt_. NB: one consequence from this equivalence is that the words that operate on the return stack cannot be defined as ordinary words (see a [corresponding discussion](https://forth-standard.org/standard/core/RFetch#reply-825)). ### System-defined semantics If the standard does not define interpretation semantics for a word, a Forth system may provide system-defined interpretation semantics for the word (see [A.3.4.3.2](https://forth-standard.org/standard/rationale#rat:interpret)). The same is true for execution semantics — if the standard does not define them for a word, a Forth system may provide system-defined execution semantics for the word. But, due to [6.1.0070](https://forth-standard.org/standard/core/Tick), performing these execution semantics in interpretation state must always be equivalent to performing the interpretation semantics for the word (regardless whether they are standard-defined or system-defined). ### Connection with Tick It we want ticking any word for which interpretation semantics are defined by the standard, `name>interpret` cannot return 0 for these words. Forth systems in which `name>interpret` returns 0 for such a word are unknown to the author. ## Solution The specification for `name>interpret` can be adjusted to solve the mentioned problem. There are two options: 1. Allow to return `0` if the system cannot return xt that identifies the interpretation semantics for the word identified by `nt` (see also the [clarification](https://forth-standard.org/proposals/clarification-for-execution-token?hideDiff#reply-1098) re execution tokens). - Probably, in this case we have to introduce a word like `name>` (experimental in Forth-83), which returns xt that identifies the execution semantics of the word identified by `nt`. Since otherwise a user-defined Forth text interpreter is impossible without [correct `find`](https://forth-standard.org/proposals/clarify-find-more-classic-approach?hideDiff#reply-682). 2. Allow to return state-dependent xt, which performs the interpretation semantics for the word in interpretation state only. In this proposal I stick to the second option. If anyone prefers the first option or has other objections, please feel free to share your ideas in a comment. ## Proposal Replace the following paragraph in the section [15.6.2.1909.20 NAME>INTERPRET](https://forth-standard.org/standard/tools/NAMEtoINTERPRET): > _xt_ represents the interpretation semantics of the word _nt_. If _nt_ has no interpretation semantics, `NAME>INTERPRET` returns 0. by the following paragraphs: > _xt_ identifies the execution semantics of the word identified by _nt_. When this _xt_ is executed in interpretation state, the interpretation semantics for the word are performed. > > If and only if interpretation semantics for the word are not defined by this standard and the Forth system does not provide the execution token for the word, `NAME>INTERPRET` returns 0. > > An ambiguous condition exists in any of the following conditions: > - interpretation semantics for the word are not defined by this standard and _xt_ is executed; > - execution semantics of the word are not defined by this standard and _xt_ is executed in compilation state; ,------------------------------------------ | 2023-09-29 07:47:52 ruv replies: | proposal - NAME>INTERPRET wording | see: https://forth-standard.org/proposals/name-interpret-wording#reply-1111 `------------------------------------------ In the ways of execution an xt the word `catch` should be mentioned. ----- The word `find` (according to the proposed [clarification](https://forth-standard.org/proposals/clarify-find-more-classic-approach?hideDiff#reply-682)) allows the program to check whether a word is ordinary (i.e., for which default interpretation semantics and default compilation semantics are defined): if and only if `find`, in interpretation state, returns `-1` at the top, then the word is ordinary. At the moment, the set of words `find-name`, `name>interpret` and `name>compile` does not provide a ways to check whether a word is ordinary. Perhaps `name>compile` could be tightened up so that analysis its result and the results of `name>interpret` allows the program to conclude whether the word is ordinary. ,------------------------------------------ | 2023-09-29 08:06:21 ruv replies: | proposal - minimalistic core API for recognizers | see: https://forth-standard.org/proposals/minimalistic-core-api-for-recognizers#reply-1112 `------------------------------------------ > `FORTH-RECOGNIZER ( -- xt )` RECOGNIZER EXT > Obtain the recognizer xt that is assigned to FORTH-RECOGNIZE. > > Rationale: > `FORTH-RECOGNIZE` is likely a deferred word, but systems that implement it otherwise, can use this word to change the behavior instead of using `ACTION-OF` `FORTH-RECOGNIZE`. The old API has this function under the name `FORTH-RECOGNIZER` (as a value) and this name is reused. Systems that want to continue to support the old API can support `TO FORTH-RECOGNIZER`, too. There is no way for a program to check whether it can apply `TO` to `FORTH-RECOGNIZER`, or `FORTH-RECOGNIZE`, or `RECOGNIZE-FORTH-LEXEME`, etc. Thus, `TO` cannot be optional. And it cannot be mandatory too. Thus, `TO` **cannot** be a part of the API at all — neither RECOGNIZER, nor RECOGNIZER EXT. Then the getter and setter should be a mandatory part of the API. ,------------------------------------------ | 2023-10-01 22:54:20 ruv replies: | proposal - minimalistic core API for recognizers | see: https://forth-standard.org/proposals/minimalistic-core-api-for-recognizers#reply-1113 `------------------------------------------ In continuation to the [message](https://forth-standard.org/proposals/minimalistic-core-api-for-recognizers#reply-1089): >> Returning something half-done isn't a good idea and makes maintaining this code difficult, as all other possibles results (like ints, floats or such) are fully converted into something useful at this stage. > This would be a valid argument if it were possible to return something useful from a recognizer in **all use cases** Another example of an unuseful token is the result of the mentioned recognizer `REC-TO`, which recognizes a syntax like `->foo`. It's too restrictive to require this token be `( xt n tt )`, since in some systems it can be just `( xt.set-value tt )`, in other — `( addr.data-field xt.store tt )`. This means that this token is not something useful to a program at all (apart of translation). ,------------------------------------------ | 2023-10-03 14:27:15 BerndPaysan replies: | comment - A better approach for SYNONYM wording | see: https://forth-standard.org/proposals/tighten-the-specification-of-synonym-version-1-#reply-1114 `------------------------------------------ With the catch-all phrase for ambiguous conditions of *name.old* and *name.new* being identical, you can drop all those child from executing one or another defining word: `TO`/`IS`/`ACTION-OF` *name.new*, etc. are identical to the same construct with *name.old*. That way, these combinations have to work even for non-standard extensions, like Gforth's, where you can define your own `TO`/`IS` semantics with `SET-TO`, regardless of the original definer. ,------------------------------------------ | 2023-10-04 12:05:48 ruv replies: | proposal - F>R and FR> to support dynamically-scoped floating point variables | see: https://forth-standard.org/proposals/f-r-and-fr-to-support-dynamically-scoped-floating-point-variables#reply-1115 `------------------------------------------ These words cannot specify how many cells on the return stack are taken (it's similar to `N>R` in this regard). Also, they should not be defined via execution semantics, but via compilation semantics and Run-time semantics. - `F>R` Run-time: `( F: r -- ) ( R: -- i*x )` Remove the top item from the floating-point stack and store it as zero or more items on the return stack for later retrieval by `FR>`. Data placed on the return stack before performing these semantics are inaccessible for a program till performing the corresponding `FR>` Run-time semantics. - `FR>` Run-time: `( F: -- r ) ( R: i*x -- )` Remove from the return stack the items previously stored by `F>R`, and place the corresponding item on the floating-point stack. ,------------------------------------------ | 2023-10-11 17:58:12 GeraldWodni replies: | example - Digests and Meta discussion | see: https://forth-standard.org/meta-discussion#reply-1116 `------------------------------------------ ### Persistent Login You can now try out the new "Remember Me" checkbox at the login. It should automatically log you in if you stay active for less than 42 days. After that the persistent login expires. Please let me know if any issues occur. ### New Digest. If all works, you should get notified about this via a newly designed `HTML` and new `TXT` digest. Fingers crossed ;) ,------------------------------------------ | 2023-10-15 01:27:26 ruv replies: | proposal - Include a revised 79-STANDARD Specification for "><" To "Core Ext" | see: https://forth-standard.org/proposals/include-a-revised-79-standard-specification-for-to-core-ext-#reply-1117 `------------------------------------------ >< fooo ,------------------------------------------ | 2023-10-15 02:45:07 ruv replies: | proposal - NAME>INTERPRET wording | see: https://forth-standard.org/proposals/name-interpret-wording#reply-1118 `------------------------------------------ `name>interpret` is allowed to return `0` if interpretation semantics for the word are not defined by the standard. But in fact, the result of `0` does not give programs any additional information, since for the same word the result can be zero in one system and non-zero in another system. So, programs won't loose anything, and will only become simpler, if `name>interpret` never returns zero (i.e., if it's required to return some xt in all cases) — since programs will not need to analyze the result (e.g. before compile or execute it). Well, in some rare cases an error report shown by programs will be carried over from compile time to runtime in some systems due to this change, but anyway this report is generated at compile time **only in some systems** — i.e., this is a system dependent behavior that programs cannot rely on. Suppose we changed the specification for `name>interpret` so that this word will require to return a system-dependent xt if interpretation semantics for the word are not defined by the standard. This change does not affect programs at all. But it affects systems — they need to be updated to comply with the new specification and new programs (which relies on the new specification). The question is: is it acceptable to change `name>interpret` specification in this way, or is it better to introduce a new word for this? The new word can be defined as follows: ``` : name> ( nt -- xt ) name>interpret dup if exit then drop [: -14 throw ;] ; ``` Or `name>interpret` can be redefined in this way in a polyfill. ,------------------------------------------ | 2023-10-15 04:35:04 ruv replies: | referenceImplementation - Imlementation seems wrong for the "-2" case | see: https://forth-standard.org/standard/exception/THROW#reply-1119 `------------------------------------------ > If the top of the stack is `-2` , and there is no handler, then `THROW` is supposed to display a message. > I can't see how the reference implementation does that. A reference implementation is just an example, it is not required to cover all the cases. The reference implementation for `THROW` is preceded by the note: "This is the counter part to [E.9.6.1.0875 `CATCH`](https://forth-standard.org/standard/implement#imp:exception:CATCH)", if we follow the link, we in turn can read in the note: "This sample implementation does not explicitly handle the case in which `CATCH` has never been called (i.e., the `ABORT` behavior)". So, the implementation explicitly says that the case of no handler is not covered. ,------------------------------------------ | 2023-10-15 04:45:26 ruv replies: | referenceImplementation - Possible Reference Implementation | see: https://forth-standard.org/standard/core/VARIABLE#reply-1120 `------------------------------------------ Both variants are correct and viable. For reference implementations, the shorter and simpler the better. And anyway, stack diagrams are required. ,------------------------------------------ | 2023-10-15 04:51:47 ruv replies: | example - | see: https://forth-standard.org/standard/core/ERASE#reply-1121 `------------------------------------------ > ``` > variable counts N allot > counts N erase > ``` This is incorrect, see [3.3.3.3 Variables](https://forth-standard.org/standard/usage#usage:var). And for example, take a look at a [possible implement for `variable`](https://forth-standard.org/standard/core/VARIABLE#contribution-232). Correct variants are as follows: ``` create counts N allot counts N erase ``` or ``` align here N allot constant counts counts N erase ``` ,------------------------------------------ | 2023-10-17 04:09:53 ruv replies: | example - | see: https://forth-standard.org/standard/file/INCLUDED#reply-1122 `------------------------------------------ > there is no similar extension to `\`, which continues to discard the entire rest of the buffer. According to the word `included` specification, it fills the input buffer with one line only. It means, the input buffer in this case contains not more than a single line, and the word [6.2.2535 \ "backslash"](https://forth-standard.org/standard/core/bs) (CORE EXT) works correctly (there is no need for update this word in the FILE word set). > when the editor evaluates its buffer then `\` comments are broken, but if it separates and evaluates each line one-at-a-time then `(` comments are broken. A possible solution of this problem is to redefine "`\`" and evaluate the whole buffer in the editor. The new behavior for the word "`\`" is to skip the characters up to the next line terminator when the `source-id` is `-1` and `blk` is `0` (otherwise no changes in behavior). This behavior is slightly not compliant, but in practice it does not cause problems in programs. > Cross-reference also ruv's post about [exactly this problem](https://github.com/ForthHub/discussion/discussions/126). Yes, my post's title is [Portable line-oriented parsing](https://github.com/ForthHub/discussion/discussions/126), and the mentioned solution is provided in the "Comments in evaluated strings" section: ``` : is-input-string ( -- flag ) \ Return a flag: is the input source a string (being evaluated). [defined] blk [if] blk @ 0<> if false exit then [then] source-id -1 = ; : source-following ( -- sd ) \ Return the parse area (a string). \ NB: the returned string may contain a line-terminator sequence in any position. source >in @ /string ; : skip-source-line ( -- ) \ Discard a part of the parse area that belongs to the current line. is-input-string 0= if ['] \ execute exit then source-following over >r s\" \n" dup >r search if drop r@ then + rdrop r> - >in +! ; : \ ( -- ) \ This Backslash works as expected in evaluated strings too skip-source-line ; immediate ``` ,------------------------------------------ | 2023-10-23 10:08:02 ruv replies: | testcase - TRAVERSE-WORDLIST must not expose the current definition | see: https://forth-standard.org/standard/tools/TRAVERSE-WORDLIST#reply-1123 `------------------------------------------ `TRAVERSE-WORDLIST` is not allowed to visit the current definition, unfinished or hidden definitions (see also the accepted proposal #153 [Traverse-wordlist does not find unnamed/unfinished definitions](https://forth-standard.org/proposals/traverse-wordlist-does-not-find-unnamed-unfinished-definitions?hideDiff#reply-487)). Some systems place the current definition into the compilation word list and change its header in such a way that this definition cannot be found via `FIND-NAME-IN` or `SEARCH-WORDLIST`. By a mistake, `nt` for this definition can be exposed by `TRAVERSE-WORDLIST`. This test ensured that the current definition is not exposed, and that the correct number of names is placed into the compilation word list. ``` : WORDLIST-LENGTH ( wid -- u ) >R 0 [: DROP 1+ TRUE ;] R> TRAVERSE-WORDLIST ; : L ( -- u ) GET-CURRENT WORDLIST-LENGTH ; T{ L :NONAME [ L ] LITERAL ; EXECUTE OVER = SWAP L = AND -> TRUE }T T{ L : TW1 [ L ] LITERAL ; TW1 OVER = SWAP 1+ L = AND -> TRUE }T ``` ,------------------------------------------ | 2023-10-23 11:36:02 ruv replies: | proposal - New words: latest-name and latest-name-in | see: https://forth-standard.org/proposals/new-words-latest-name-and-latest-name-in#reply-1124 `------------------------------------------ ## Author Ruv ## Change Log - 2023-10-22 Initial revision - 2023-10-23 Add testing, examples, a question to discuss, change the throw code description ## 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](https://groups.google.com/g/comp.lang.forth/c/RsJQVnEQQuw/m/M1PrzPAcE-0J) 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](https://forth-standard.org/standard/tools#subsection.15.6.2)), 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: 1. A word list contains only completed definitions (see the accepted proposal #153 [Traverse-wordlist does not find unnamed/unfinished definitions](https://forth-standard.org/proposals/traverse-wordlist-does-not-find-unnamed-unfinished-definitions?hideDiff#reply-487)). This eliminates the question of whether the word of returned _nt_ is finished — yes, it is always finished (completed). 2. 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). 3. 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. ## Things to discuss Is it worth introducing the word `LATEST-NAME-XT ( -- xt )`? If `name>interpret` never returns `0` (see my [comment](https://forth-standard.org/proposals/name-interpret-wording?hideDiff#reply-1118)), this word can be implemented as: ``` : latest-name-xt ( -- xt ) latest-name name>interpret ; ``` The desired (and much discussed) pattern is: ``` defer bar : foo ... ; latest-name-xt is bar ``` Sometimes the name "`it`" has been suggested for this word, but this name is too short and has more chance for conflicts. Guido Draheim [wrote](https://groups.google.com/g/comp.lang.forth/c/_WCxDv1qd2M/m/dZp-OAryvt8J) in `comp.lang.forth` on 2003-03-16: > I think that everyone has been thinking of using `IT` for something really clever, it's a nice short word - and I'd say that we should leave it for application usage. > > I want to support that argument also with real life experience in the telco world where there are a whole lot of abbreviations for various services, signals, connectors around. All too often now I see people making a SYNONYM at the file-start to get a second name for an ANS forth word that is needed in the implemenation but coincides with a common term of the application. This seems convincing to me. ## Typical use ``` : STRUCT: ( "name" -- wid.current.old u.offset ) GET-CURRENT VOCABULARY ALSO LATEST-NAME NAME> EXECUTE DEFINITIONS 0 ; ``` ``` \ In the application's vocabulary : IT ( -- xt ) LATEST-NAME NAME>INTERPRET ; DEFER FOO : BAR ... ; IT IS FOO ``` ## Proposal Add the following line into the [Table 9.1: THROW code assignments](https://forth-standard.org/standard/exception#table:throw): > `-80` latest name is missing Add the following sections into [15.6.2 Programming-Tools extension words](https://forth-standard.org/standard/tools#subsection.15.6.2): #### 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 ; ``` ## Testing ``` : IT ( -- xt ) LATEST-NAME NAME>INTERPRET ; T{ : LN1 ; IT ' LN1 = -> TRUE }T T{ :NONAME [ IT ] LITERAL ; EXECUTE ' LN1 = -> TRUE }T T{ : LN2 [ IT ] LITERAL ; LN2 ' LN1 = -> TRUE }T ```