In the above we show how to define a word by first using
create
, and then modifying it with set-does>
,
set-to
, set-optimizer
etc.
An alternative way is to create a prototype using these words, and
then create a new word from that prototype. This kind of copying does
not cover the body, so that has to be allocated and initialized
explicitly. Taking fvalue
above, we could instead define it
as:
create fvalue-prototype ( -- r ) ['] f@ set-does> [: >body ]] literal f@ [[ ;] set-optimizer ['] fvalue-to set-to : fvalue ( r "name" -- ; name: -- r ) ``fvalue-prototype create-from f, reveal ;
An advantage of this approach is that creating fvalue
words is
now faster, because it does not need to first duplicate the header
methods of create
, modify them, and eventually deduplicate
them. But this advantage is only relevant if the number of words
created with this defining word is huge.
create-from
( nt "name" – ) gforth-1.0 “create-from”
Create a word name that behaves like nt, but with an
empty body. nt must be the nt of a named word. The
resulting header is not yet reveal
ed; use reveal
to reveal it or latest
to get its xt. Creating a word
with create-from
without using any set-
words is
faster than if you create a word using set-
words,
immediate
, or does>
. You can use noname
with create-from
.
reveal
( – ) gforth-0.2 “reveal”
Put the current word in the wordlist current at the time of the header definition.
reveal!
( xt wid – ) core-ext “reveal-store”
Add xt to a wordlist. Mapped to DEFER!
.
The performance advantage does not extend to using noname
with
the defining word. Therefore we also have
noname-from
( xt – ) gforth-1.0 “noname-from”
Create a nameless word that behaves like xt, but with an empty body. xt must be the nt of a nameless word.
Here’s a usage example:
``fvalue-prototype noname create-from latestnt constant noname-fvalue-prototype : noname-fvalue ( r -- xt ; xt execution: -- r ) noname-fvalue-prototype noname-from f, latestxt ;