Digest #125 2020-11-28
A string is specified by a cell pair (c-addr u) representing its starting address and length in characters.
xd — unspecified cell pair — 2 cells
Don't you think it's convenient to have a symbol for a cell pair (c-addr u) representing a string?
For example, sd or just s ?
As a result, the stack notation for words that handle strings can be more concise. So, we will have an option to write ( sd1 ) instead of ( c-addr1 u1 ).
Correct. An alternative implementation:
: definitions ( -- ) get-order over set-current set-order ;
The Rationale for this proposal was split away by Matthias Trute to satisfy complaints about the length of the proposal, but can be useful in understanding the design decisions.
that I think it's inadequate to restrict xt to only refer to execution semantics.
I thought about this problem. And I came to the following reasoning.
Have a look at the following example:
: foo postpone if ; : bar foo ; ' foo ( xt-foo ) ' bar ( xt-bar )
xt-bar identifies the execution semantics for
bar. But these semantics are equivalent to the execution semantics for
foo. Then, xt-bar also identifies the execution semantics for
Then, xt-foo and xt-bar identify the same execution semantics (and they even may be equal, according to 184.108.40.206 Execution tokens).
But the execution semantics for
foo are equivalent to the compilation semantics for
if. Then xt-foo also identifies the compilation semantics for
if. And performing the execution semantics identified by xt-foo is equivalent to performing the compilation semantics for
But you claim that an execution token cannot identify compilation semantics. What is wrong?
My conclusion is that any execution token always identifies some execution semantics, and at the same time it identifies any other semantics that are equivalent to these execution semantics.
I.e., an execution token cannot identify only some compilation semantics alone, but it identify execution semantics and the compilation semantics that are equivalent to these execution semantics.
So we may say that an execution token identifies some compilation semantics (for example), but it shall imply that this execution token also identifies the equivalent execution semantics, and when
execute is applied to this token, these execution semantics are performed. Ditto for
If an xt identifies some interpretation semantics, it just means that it identifies the execution semantics that are equivalent to these interpretation semantics.
Therefore, we don't have any problems on the side of execution token consumers.
Concerning the producers side
NAME>COMPILEspecification doesn't imply that the returned xt identifies something other then some execution semantics.
NAME>INTERPRETspecification can use "identify" instead of represent: "xt identifies the execution semantics that are equivalent to the interpretation semantics for the word nt". But it still doesn't mean that it returns the same value that Tick returns for the same word.
[']) implies that the returned xt identifies the execution semantics for the word in the argument. My proposal fixes some edge cases of using Tick.
The term "execution token" is correctly used in
FIND(at least, it's correct for single-xt systems, and acceptable for dual-nt systems), but single-nt+dual-xt Forth systems don't exactly reflect specification of
FINDshould be updated in this regard, since "its execution token xt" sometimes is not correct in single-nt+dual-xt systems.
Problem with "executable code"
Do we have non executable code?
"Executable code" doesn't have any connection with semantics. It looks like a model of a far lower level.
Tick returns "the execution token for name", that means an identifier of the execution semantics for name. So applying
executeto this xt performs the execution semantics for name. After the proposed update, Tick returns an identifier of some "executable code" for name. When
executeis applied to this xt, what semantics are performed? It's unclear.
Gforth's new header structure allows to overload
IS (which are essentially the same) and
DEFER@, so we can use the
DEFER API to access similar changeable execution patterns implemented differently. So for us, it makes sense to use these access words, regardless how it is implemented.
Other systems may not have this capability, though the way the standard now extends
FVALUE and others, you need to have one way or the other to deal with that. Same, when you have an
UDEFER in your system for user-specific deferred words.
For me, it is needless clutter of the dictionary and the mental space of the programmer to add setters and getters for things where you already have a generic one. But I see the point that not every system can do this.
needless clutter of the dictionary and the mental space of the programmer
I used an approach when a defined word creates two words — a getter and a setter.
It's something like after the phrase
create-prop x the words
set-x are created. I didn't noticed any mental space clutter in this regard. Sometimes I redefined
set-x to add additional checks or actions.
Concerning dictionary space — I don't see any problem.
But I see the point that not every system can do this.
True. And even if a system can do this, it's done in some system specific way only.
So, due to the combination of all reasons, it's better to have distinct ordinary words in the standard API.