• NEXTNAME or sins of the past

    From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Mon Jan 5 09:52:09 2026
    From Newsgroup: comp.lang.forth

    Gforth had had NEXTNAME ( c-addr u - ) since the beginning. Its
    effect is that the next execution of a defining word uses c-addr u for
    the name and does not try to parse it from the input stream. This is
    useful for creating words with names that have been created in the
    program.

    I have never liked the stateful interface of NEXTNAME: there is some
    global (or, at best, user) storage that contains the name, and there
    is also a deferred word that tells the word-creating word what to do
    in order to get the name of the word.

    A more recent (since Gforth-0.6) alternative to using NEXTNAME is to
    use EXECUTE-PARSING, which is somewhat cleaner (the word-creating word
    just parses the name, no deferred word in header-creation necessary),
    but has its own limitations; e.g., the name must not contain white
    space (whereas NEXTNAME does not have this limitation).

    And I have finally been bitten by this interface (and our
    implementation of this interface): For the defining word LOCALE:
    (which defines, unsurprisingly, a locale), I wanted to make it such
    that it creates the locale only if it does not exist already. But
    LOCALE: is also called from a word that passes the name through
    NEXTNAME to LOCALE:.

    Unfortunately, the implementation of NEXTNAME hooks into the header
    creation of defining words, not into the name parsing of the defining
    word, so I cannot just check the name and only then call the
    header-creation stuff. So instead I changed the part of the code that
    actually clled NEXTNAME, but that did not affect direct invocations of
    LOCALE:; for those I just documented the behaviour, which is more
    cumbersome than I like.

    I guess we will deal with the problem at a later stage, but it will
    probably require quite a bit of changes in Gforth.

    Anyway, the bottom line is: stateful interfaces eventually bite you.

    - 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: https://forth-standard.org/
    EuroForth 2025 CFP: http://www.euroforth.org/ef25/cfp.html
    EuroForth 2025 registration: https://euro.theforth.net/
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From albert@albert@spenarnc.xs4all.nl to comp.lang.forth on Mon Jan 5 12:35:30 2026
    From Newsgroup: comp.lang.forth

    In article <2026Jan5.105209@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    Gforth had had NEXTNAME ( c-addr u - ) since the beginning. Its
    effect is that the next execution of a defining word uses c-addr u for
    the name and does not try to parse it from the input stream. This is
    useful for creating words with names that have been created in the
    program.

    I have never liked the stateful interface of NEXTNAME: there is some
    global (or, at best, user) storage that contains the name, and there
    is also a deferred word that tells the word-creating word what to do
    in order to get the name of the word.

    I think that the solution is the other way around. If you have to have
    CONSTANT that takes a string from the stack, call it (CONSTANT). Lean
    on (CREATE) that does a similar thing creating a multi purpose header
    with a name on the stack that can later be filled in.


    A more recent (since Gforth-0.6) alternative to using NEXTNAME is to
    use EXECUTE-PARSING, which is somewhat cleaner (the word-creating word
    just parses the name, no deferred word in header-creation necessary),
    but has its own limitations; e.g., the name must not contain white
    space (whereas NEXTNAME does not have this limitation).

    ciforth solution use SAVE / RESTORE
    and SET-SRC. (instead of EXECUTE-PARSING)
    : :CONSTANT SAVE SET-SRC CONSTANT RESTORE ;

    Usage: 12 "aap" :CONSTANT

    Note that there is no new inventions here. These words are useful
    and actually used to define the Forth kernel.
    E.g. this is the definition of EVALUATE

    : EVALUATE
    SAVE SET-SRC 'INTERPRET CATCH RESTORE THROW
    ;

    (SAVE is a leaner version of SAVE-INPUT but saves the information
    of the return stack, as is the habit for all call/return sequences
    on the planet.)

    On its turn the INTERPRET is used in QUIT: the repl loop .


    And I have finally been bitten by this interface (and our
    implementation of this interface): For the defining word LOCALE:
    (which defines, unsurprisingly, a locale), I wanted to make it such
    that it creates the locale only if it does not exist already. But
    LOCALE: is also called from a word that passes the name through
    NEXTNAME to LOCALE:.

    Unfortunately, the implementation of NEXTNAME hooks into the header
    creation of defining words, not into the name parsing of the defining
    word, so I cannot just check the name and only then call the
    header-creation stuff. So instead I changed the part of the code that >actually clled NEXTNAME, but that did not affect direct invocations of >LOCALE:; for those I just documented the behaviour, which is more
    cumbersome than I like.

    I guess we will deal with the problem at a later stage, but it will
    probably require quite a bit of changes in Gforth.

    Anyway, the bottom line is: stateful interfaces eventually bite you.

    I do not understand the issue fully. I just hope my solution is not
    stateful.

    P.S.
    EXECUTE-PARSING is readily defined, but you will hardly ever use it:

    : EXECUTE-PARSING
    ROT ROT SAVE SET-SRC CATCH RESTORE THROW
    ;


    - anton

    Groetjes Albert
    --
    The Chinese government is satisfied with its military superiority over USA.
    The next 5 year plan has as primary goal to advance life expectancy
    over 80 years, like Western Europe.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Mon Jan 5 12:39:25 2026
    From Newsgroup: comp.lang.forth

    albert@spenarnc.xs4all.nl writes:
    In article <2026Jan5.105209@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    I think that the solution is the other way around. If you have to have >CONSTANT that takes a string from the stack

    That would have been a good solution if it had been in Forth from the
    beginning (but that would have required stronger string support in the
    original Forth). However, that has not happened, and the only
    standardized defining words for named word take the name from the
    input stream, with one exception: (LOCAL) (which is hardly ever used).
    And therefore user-defined defining words also take the name from the
    input stream.

    So, given this state of things, one may wish that things were
    different, and define (CONSTANT), (CREATE), etc. (which BTW will be
    hated by everyone who uses ( ... ) to comment out code), and hope that everybody goes along and rewrites their defining words to take a
    string from the stack, and then also writes a parsing counterpart, or alternatively, rewrites all the uses of the defining word.

    Alternatively, one can think about how to make existing (parsing)
    defining words work when we have the name as a string on the stack.
    One solution is NEXTNAME, another one (which also works for other
    parsing words) is EXECUTE-PARSING.

    In the ~30 years since NEXTNAME was introduced, the Forth world has not converted itself to using defining words that take the name from the
    stack. In an alternate history where Gforth would have introduced
    (CONSTANT), (CREATE) etc. instead, I expect that the result would have
    been the same, so NEXTNAME has been the better approach given the
    situation has been as it has been.

    A more recent (since Gforth-0.6) alternative to using NEXTNAME is to
    use EXECUTE-PARSING, which is somewhat cleaner (the word-creating word
    just parses the name, no deferred word in header-creation necessary),
    but has its own limitations; e.g., the name must not contain white
    space (whereas NEXTNAME does not have this limitation).

    ciforth solution use SAVE / RESTORE
    and SET-SRC. (instead of EXECUTE-PARSING)
    : :CONSTANT SAVE SET-SRC CONSTANT RESTORE ;

    Please show the documentation for SAVE SET-SRC and RESTORE. The
    documentation for EXECUTE-PARSING is:

    |'execute-parsing' ( ... addr u xt - ... ) gforth-0.6
    | Make addr u the current input source, execute xt '( ... -- ... )',
    |then restore the previous input source.

    I had been thinking along the lines of word like SAVE SET-SRC and
    RESTORE myself, but it becomes incredibly messy to specify what these
    words do in isolation. And if you specify them (by having them push
    opaque system types) such that they can only be used in this combo,
    why have this combo instead of a single word that is still easier to
    specify?

    BTW, why do you call it :CONSTANT here, not (CONSTANT) like above?
    Did I miss something about (CONSTANT)?

    EXECUTE-PARSING is readily defined, but you will hardly ever use it:

    I have used it many times.

    - 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: https://forth-standard.org/
    EuroForth 2025 CFP: http://www.euroforth.org/ef25/cfp.html
    EuroForth 2025 registration: https://euro.theforth.net/
    --- Synchronet 3.21a-Linux NewsLink 1.2