On 2024-10-05 19:52, Anton Ertl wrote:
Ruvim <ruvim.pinka@gmail.com> writes:
On 2024-10-04 22:04, Anton Ertl wrote:
Ruvim <ruvim.pinka@gmail.com> writes:
On 2024-10-04 15:52, Anton Ertl wrote:
It can be defined: Gforth has SET-TO
...
I wonder why a kind of "TO" is not used to set this field/property, and
*maybe* a kind of "ACTION-OF" to get this property.
>
Interesting idea. Maybe in some future version.
Thinking some more about it, better not:
SET-TO SET-OPTIMIZER etc. all work on the latest definition.
I assumed that there are methods under the hood that work on any given definition, not the latest one. Or such methods could be defined.
The methods that they set work on an NT or XT passed on the stack.
The usual behaviour of defer-flavoured words is that the context is
the same. If you have
defer d
' foo is d
action-of d
That's always the same global D. For a defer-flavoured field,
likewise:
0
value: vf
defer: df
constant mystruct
create foo mystruct allot
1 foo to vf
' . foo is df
foo vf .
2 foo df
So having TO TO instead of SET-TO would disobey this principle.
I see. I mean methods to access/change a property of any given word, namely the "TO name run-time" semantics.
Let the *setter* for a word is an execution token that identifies "TO name run-time" semantics for the word.
(I understand that in Gforth, the xt of a word is passed to the method that implements "to", but I consider a simpler variant)
There are several approaches to access or assign the setter for a word.
1. "to-based" approach, but with special words instead of "is" and "action-of".
\ setter-to ( xt.setter "name" -- )
\ setter-of ( "name" -- xt.setter )
\ Usage example
0 value foo
1 setter-of foo execute
foo . \ prints "1"
[: ( u -- )
dup 10 u> abort" too big value for x"
[ setter-of foo compiler, ]
;] setter-to foo
Disadvantages:
- a visually *unmarked* immediate argument in the input stream,
- inconvenient to work with nt.
2. "to-based" approach for structures
\ name>setter ( nt -- xt.setter )
\ to name>setter ( xt.setter nt -- )
\ Usage example
0 value foo
1 "foo" find-name name>setter execute
foo . \ prints "1"
[: ( u -- )
dup 10 u> abort" too big value for x"
[ "foo" find-name name>setter compiler, ]
;] "foo" find-name to name>setter
Disadvantages:
- a visually *unmarked* immediate argument in the input stream,
- the phrase `"foo" find-name to name>setter`
does look like we are storing an nt from `find-name` into `name>setter`. (this is the same as for structures)
A solution for the latter: use another name instead of "to"
For example, "to-field"
"foo" find-name to-field name>setter
A solution for the former: mark the input argument. For example:
"foo" find-name to-field( name>setter )
3. Simple words
\ name>setter ( nt -- xt.setter )
\ name-setter! ( xt.setter nt -- )
\ Usage example
0 value foo
1 "foo" find-name name>setter execute
foo . \ prints "1"
[: ( u -- )
dup 10 u> abort" too big value for x"
[ "foo" find-name name>setter compiler, ]
;] "foo" find-name name-setter!
Disadvantages are unknown.
For COMPILE, there is the additional problem that it is a deferred
word, so when you do "IS COMPILE," you change the behaviour for all
uses of "COMPILE,", not just of the latest definition. The actual
method of each definition is called OPT-COMPILE,.
In the to-based approach, "compile," should behave like a field in a structure.
Taking into account that an optimizer (or a special compiler) should be associated with an xt (not with an nt), this could look as:
[: ( xt -- ) >body lit, ['] @ compile, ;]
' foo is compiler,
Or, with less disadvantages:
[: ( xt -- ) >body lit, ['] @ compile, ;]
' foo to-field( xt-compiler )
\ where
: compile, ( xt -- ) dup xt-compiler execute ;
All of the above are just ideas.
-- Ruvim