------
: NONDEFERRED ;
SYNONYM
On 9/28/22 19:39, Krishna Myneni wrote:
------
: NONDEFERRED ;
SYNONYM
The above line should have been
SYNONYM A@ @
--
Forth 2012 standardizes the words FVALUE and 2VALUE which, like VALUE,
work with TO. Thus, the typed value contains in addition to the datum
another data field indicating the execution semantics for TO. Recently I >revised the implementation of TO and VALUE in kForth-64, using
standardized Forth 200x source, to support FVALUE and 2VALUE. It turned
out to be beneficial to use the name token (nt) instead of using the
(xt) for informing TO of how to compile the execution semantics in
kForth. This is because, for primitive words (those built-in to the >dictionary), the sequence
( xt addr -- ) POSTPONE LITERAL POSTPONE LITERAL POSTPONE EXECUTE
generates less efficient code for primitive words than the sequence
( nt addr -- ) POSTPONE LITERAL NAME>COMPILE EXECUTE
-- Krishna Myneni
...
I have taken the stand that xt should be ditched for nt (dea, Dictionary Entry Address). All what is accomplished by xt can be done better by nt, because there is more information available.
To those who are concerned with efficiency (read speed), they are
invited to add some optimizing to the resulting code.
The xt is a half assed concept introduced by ISO 93, when we did not
know better.
...
I have taken the stand that xt should be ditched for nt (dea, Dictionary
Entry Address). All what is accomplished by xt can be done better by nt,
because there is more information available.
To those who are concerned with efficiency (read speed), they are
invited to add some optimizing to the resulting code.
The xt is a half assed concept introduced by ISO 93, when we did not
know better.
Needs vary. Nearly every application I write ditches the dictionary in >favour of the space it occupied. That's a 35% gain in free memory at >run-time.
In article <th2pfa$fmrn$1@dont-email.me>,...
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
Forth 2012 standardizes the words FVALUE and 2VALUE which, like VALUE,
work with TO. Thus, the typed value contains in addition to the datum
another data field indicating the execution semantics for TO. Recently I
revised the implementation of TO and VALUE in kForth-64, using
standardized Forth 200x source, to support FVALUE and 2VALUE. It turned
out to be beneficial to use the name token (nt) instead of using the
(xt) for informing TO of how to compile the execution semantics in
kForth. This is because, for primitive words (those built-in to the
dictionary), the sequence
( xt addr -- ) POSTPONE LITERAL POSTPONE LITERAL POSTPONE EXECUTE
generates less efficient code for primitive words than the sequence
( nt addr -- ) POSTPONE LITERAL NAME>COMPILE EXECUTE
I have taken the stand that xt should be ditched for nt (dea, Dictionary Entry Address). All what is accomplished by xt can be done better by nt, because there is more information available.
So how come there is a data type smart word (TO) in Forth? Are there any others ?
I have implemented 2TO instead. Is the smart TO in the standard ? Are locals the reason for it?
On 9/29/22 05:05, Mike wrote:
So how come there is a data type smart word (TO) in Forth? Are there
any others ?
I have implemented 2TO instead. Is the smart TO in the standard ? Are
locals the reason for it?
The implementation of TO is not data-type smart -- it can be used on any arbitrary data type of VALUE. The execution semantics for TO are
obtained from the value, i.e. the information about how to store the a
new value is contained into the named value is contained in the named
value.
So how come there is a data type smart word (TO) in Forth? Are there any others ?
Krishna Myneni schrieb am Donnerstag, 29. September 2022 um 02:43:10 UTC+2:
On 9/28/22 19:39, Krishna Myneni wrote:
------
: NONDEFERRED ;
SYNONYM
The above line should have been
SYNONYM A@ @
--
Thanks for posting this!
It is refreshing to read some substantial contribution again
here in c.l.f., instead of all those silly rantings of the last months.
I was only wondering if your idea could be extended to +TO.
In article <th3om4$10lr$1@gioia.aioe.org>, dxforth <dxforth@gmail.com> wrote:
On 29/09/2022 6:54 pm, albert wrote:That is a non-sequitur.
...
I have taken the stand that xt should be ditched for nt (dea, Dictionary >>> Entry Address). All what is accomplished by xt can be done better by nt, >>> because there is more information available.
To those who are concerned with efficiency (read speed), they are
invited to add some optimizing to the resulting code.
The xt is a half assed concept introduced by ISO 93, when we did not
know better.
Needs vary. Nearly every application I write ditches the dictionary in
favour of the space it occupied. That's a 35% gain in free memory at
run-time.
So how come there is a data type smart word (TO) in Forth? Are thereany others ?
So state-smart words are bad — but data-type-smart words are (still?) good? ;)
Is the smart TO in the standard ?
Are locals the reason for it?
------
: NONDEFERRED ;
SYNONYM A@ @
: TO ( i*x "name" -- ) \ or ( F: i*r -- ) ( "name" -- )
' >body
dup a@ swap cell+
state @ IF
postpone literal
name>compile execute
ELSE
swap name>interpret execute
THEN ; immediate
: xVALUE ( i*x nt-put usize -- ) ( F: j*r -- )
create 1 cells + allot? \ -- i*x nt-put a
2dup ! cell+ swap name>interpret execute immediate nondeferred
;
: VALUE ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
does> cell+ state @ if postpone literal postpone @
else @ then ;
: 2VALUE ( x1 x2 "name" -- )
[ s" 2!" find-name ] literal 2 cells xVALUE
does> cell+ state @ if postpone literal postpone 2@
else 2@ then ;
: FVALUE ( F: r -- ) ( "name" -- )
[ s" F!" find-name ] literal 1 floats xVALUE
does> cell+ state @ if postpone literal postpone f@
else f@ then ;
------
So state-smart words are bad
=E2=80=94 but data-type-smart words are (still=
?) good? ;)
more people sing the praises of value-flavoured words and TO
Mike <oh2...@gmail.com> writes:
Is the smart TO in the standard ?Yes.
Are locals the reason for it?In Forth-94 TO works on VALUEs and locals, so one might answer "yes"
to your question; or one might say that VALUEs are the reason for it.
It certainly is interesting that people went for using TO for all
kinds of value-flavoured words, while we have ! 2! F! C! etc. for variable-flavoured words. I guess the reason is that TO takes a word,
and the Forth system can determine what kind of word it is, while !
etc. take an address on the stack, and a traditional Forth system
cannot determine what kind of address it is.
One could still argue that TO 2TO FTO etc. would be simpler, but
apparently people are prepared to pay the price of a little complexity
for the convenience of a polymorphic TO.
- anton
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
------
: NONDEFERRED ;
SYNONYM A@ @ ...
Vade retro, STATE-smartness!
For comparison, here's a simplified version of Gforth's implementation
of TO:
--------------------
\ First, the method implementation of the method (TO) for VALUEs:
: value-to ( n value-xt -- ) \ gforth-internal
\g this is the TO-method for normal values
>body ! ;
: value ( n "name" -- )
create ,
['] @ set-does> \ like DOES> @ ;
['] value-to set-to \ The method implementation for (TO) is now VALUE-TO ;
: name>(to) ( nt -- xt-(to-implementation )
\ given an nt, the following magic incantation produces the xt of
\ the (TO) implementation of the word represented by nt.
>namehm @ >hmto @ ;
... The improved efficiency is realized because NAME>COMPILE can
recognize a primitive word and generate byte code for a direct call to
the primitive word rather than indirect execution via EXECUTE --
basically NAME>COMPILE permits a compiler-specific optimization in
kForth, which would otherwise not be possible if one were dealing with
xt's.
Zbig <zbigniew2011@gmail.com> writes:
So state-smart words are bad
They are evil! [ertl98]
On my systems variables and values also produce the same code
This is from the tokenized code of nft64/lxf64
0 value v1 ok
variable v2 ok
: t1 111 to v1 ; ok
: t2 111 v2 ! ; ok
Is there a way to implement TO
VALUE 2VALUE and FVALUE per the standard using *only* standard Forth
words and no state-smart definitions?
Yes, my implementation is state-smart. Is there a way to implement TO
VALUE 2VALUE and FVALUE per the standard using *only* standard Forth
words and no state-smart definitions?
Krishna
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
Is there a way to implement TO
VALUE 2VALUE and FVALUE per the standard using *only* standard Forth
words and no state-smart definitions?
I don't see the value of the restriction "using *only* standard Forth
words", but actually there is:
-------------------
variable val-action 0 val-action !
: to 1 cells val-action ! ;
create value-actions ' @ , ' ! ,
create 2value-actions ' 2@ , ' 2! ,
create fvalue-actions ' f@ , ' f! ,
: value ( x "name" -- )
create ,
does> ( name: -- x; to name: x -- )
value-actions val-action @ + @ execute
0 val-action ! ;
: 2value ( x1 x2 "name" -- )
create ,
does> ( name: -- x1 x2; to name: x1 x2 -- )
2value-actions val-action @ + @ execute
0 val-action ! ;
: fvalue ( r "name" -- )
create ,
does> ( name: -- r; to name: r -- )
fvalue-actions val-action @ + @ execute
0 val-action ! ;
-------------------
In article <th5dms$psea$1@dont-email.me>,
Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
<SNIP>
Yes, my implementation is state-smart. Is there a way to implement TO
VALUE 2VALUE and FVALUE per the standard using *only* standard Forth
words and no state-smart definitions?
It is easy and it is trivial, but not fast.
See VALUE in the .lab blocks.
It has long appreciated that values are poor man's
message interpretating objects. See the documentation
for tforth (A.D. 1994).
-------------------
( VALUE TO FROM ) \ AvdH B2aug07
VARIABLE TO-MESSAGE \ 0 : FROM , 1 : TO .
DATA _value_jumps '@ , '! , '+! ,
: FROM 0 TO-MESSAGE ! ;
\ ISO
: TO 1 TO-MESSAGE ! ;
\ Signal that we want to add to value
: +TO 2 TO-MESSAGE ! ;
\ ISO
: VALUE CREATE , DOES> _value_jumps TO-MESSAGE @ CELLS +
@ EXECUTE FROM ;
-------------------
There was a discussion about the original ANSI 93 rule
that "TO must parse". However it has been established that
there is no standard conforming program that can test
whether that is the case. Shooting down/ignoring that
remark is part of the argument that non state smart
implementations stands.
A dual semantics system such as Gforth, or a system which can override default compilation semantics (e.g. I believe VFX has a word called
NDCS: for doing this) is helpful to overcome the tradeoff.
A dual semantics system such as Gforth, or a system which can override default compilation semantics (e.g. I believe VFX has a word called
NDCS: for doing this) is helpful to overcome the tradeoff.
A previous response seems to have become garbled, so here it is again.
On 30 Sep 2022 at 13:05:51 CEST, "Krishna Myneni" <krishna.myneni@ccreweb.org>
wrote:
A dual semantics system such as Gforth, or a system which can override
default compilation semantics (e.g. I believe VFX has a word called
NDCS: for doing this) is helpful to overcome the tradeoff.
I have written several EuroForth papers about implementing words with non-default compilation semantics in a standards-compliant way. NDCS: is one of the support words. The other change you would probably need to make is to have an NDCS bit in the dictionary header.
One of the interesting impacts of this is that the IMMEDIATE bit can go away, and an IMMEDIATE word is just an NDCS word with the same actions in interpretation and compilation states.
The simplicity of the final solution implemented in VFX (all versions) is one of the things that convinces me that the solution is correct. VFX is supplied with full source code. See kernel.fth or kernel64.fth.
If I wanted to use my implementation of extended VALUEs with NDCS: to
remove state-smart words, how would the following words be modified?
: TO ( i*x "name" -- ) \ or ( F: i*r -- ) ( "name" -- )
' >body
dup a@ swap cell+
state @ IF
postpone literal
name>compile execute
ELSE
swap name>interpret execute
THEN ; immediate
: VALUE ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
does> cell+ state @ if postpone literal postpone @
else @ then ;
Something is not quite right with the compilation semantics of your
revised TO.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
If I wanted to use my implementation of extended VALUEs with NDCS: to
remove state-smart words, how would the following words be modified?
: TO ( i*x "name" -- ) \ or ( F: i*r -- ) ( "name" -- )
' >body
dup a@ swap cell+
state @ IF
postpone literal
name>compile execute
ELSE
swap name>interpret execute
THEN ; immediate
This is a parsing word. Here you want compilation semantics that
differ from both default and immediate compilation semantics, so a
word like COMPSEM: (or the more beautiful VFX name NDCS:) is
appropriate. You can define TO as follows (untested):
require set-compsem.fs
: to ( i*x "name" -- )
' >body dup a@ swap cell+ swap name>interpret execute ;
compsem: ' >body dup a@ swap cell+ postpone literal name>compile execute ;
: VALUE ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
does> cell+ state @ if postpone literal postpone @
else @ then ;
The word defined by a VALUE has default compilation semantics, so
COMPSEM: is wrong (and STATE-smartness is wrong, too; it's not hard to construct an example where this VALUE misbehaves).
What you are trying to do here is to optimize the compiled code, so
you can define value as follows:
: value-does> does> cell+ @ ;
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
value-does>
[: >body cell+ postpone literal postpone @ ;] set-optimizer ;
In VFX SET-OPTIMIZER is called SET-COMPILER, which misleads people
into believing that it changes the compilation semantics.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
Something is not quite right with the compilation semantics of your
revised TO.
It turns out that the compilation semantics of the words created with
xVALUE was wrong (it created immediate values).
Here's a working version:
\ values2.4th
require set-compsem.fs
\ include contrib/kforth-compat.fs
synonym a@ @
: to ( i*x "name" -- )
' >body dup a@ swap cell+ swap name>interpret execute ;
compsem: ' >body dup a@ swap cell+ postpone literal
name>compile execute ;
: xVALUE ( i*x nt-put usize -- ) ( F: j*r -- )
create 1 cells + here >r allot r> \ -- i*x nt-put a
2dup ! cell+ swap name>interpret execute ;
: value-does> does> cell+ @ ;
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
value-does>
[: >body cell+ postpone literal postpone @ ;] set-optimizer ;
\ tests
5 value n1
n1 .
7 to n1
n1 .
: test1 n1 . ;
cr test1
see test1
: test n1 n1 + to n1 ;
cr test n1 .
see test
On 9/30/22 15:56, Anton Ertl wrote:...
Here's a working version:
\ values2.4th
require set-compsem.fs
\ include contrib/kforth-compat.fs
synonym a@ @
: to ( i*x "name" -- )
' >body dup a@ swap cell+ swap name>interpret execute ;
compsem: ' >body dup a@ swap cell+ postpone literal
name>compile execute ;
: xVALUE ( i*x nt-put usize -- ) ( F: j*r -- )
create 1 cells + here >r allot r> \ -- i*x nt-put a
2dup ! cell+ swap name>interpret execute ;
: value-does> does> cell+ @ ;
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
value-does>
[: >body cell+ postpone literal postpone @ ;] set-optimizer ;
I still don't get how SET-OPTIMIZER works. Earlier you stated,
"In VFX SET-OPTIMIZER is called SET-COMPILER, which misleads people
into believing that it changes the compilation semantics."
Doesn't SET-OPTIMIZER change the compilation semantics of the words
created by VALUE 2VALUE etc.?
One may also eliminate the intermediate value-does> word(s) using...
quotations.
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-optimizer ;
On 9/30/22 04:30, albert wrote:
There was a discussion about the original ANSI 93 rule
that "TO must parse".
Yes, I was stuck on the notion of a parsing TO which led to my
particular implementation. The restriction in the Forth 2012 standard
that "An ambiguous condition exists if any of POSTPONE, [COMPILE], '
(tick) or ['] are applied to TO." (6.2.2295) is apparently a concession
to the allowance for implementing a parsing TO.
On 9/30/22 02:20, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:...
Is there a way to implement TO
VALUE 2VALUE and FVALUE per the standard using *only* standard Forth
words and no state-smart definitions?
I don't see the value of the restriction "using *only* standard Forth
words", but actually there is:
-------------------
variable val-action 0 val-action !
: to 1 cells val-action ! ;
create value-actions ' @ , ' ! ,
create 2value-actions ' 2@ , ' 2! ,
create fvalue-actions ' f@ , ' f! ,
: value ( x "name" -- )
create ,
does> ( name: -- x; to name: x -- )
value-actions val-action @ + @ execute
0 val-action ! ;
: 2value ( x1 x2 "name" -- )
create ,
does> ( name: -- x1 x2; to name: x1 x2 -- )
2value-actions val-action @ + @ execute
0 val-action ! ;
: fvalue ( r "name" -- )
create ,
does> ( name: -- r; to name: r -- )
fvalue-actions val-action @ + @ execute
0 val-action ! ;
-------------------
Ok, thanks. The value in being able to implement with only standard
Forth code is that the functionality can be added quickly to a Forth
system, without tampering with the system itself, and used to check
whether or not there will be any side effects from the extensions to
existing Forth programs.
On 9/29/22 11:56, Anton Ertl wrote:[...]
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
[...]
: VALUE ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
does> cell+ state @ if postpone literal postpone @
else @ then ;
...------
Vade retro, STATE-smartness!
Yes, my implementation is state-smart.
Is there a way to implement TO VALUE 2VALUE and FVALUE
per the standard using *only* standard Forth
words and no state-smart definitions?
The actual problem is that your implementation is not
standard-compliant. Namely, the words defined by this VALUE have STATE-dependent execution semantics (according to the does-part), while
the standard doesn't specify that [2]:
| name Execution:
| ( -- x )
|
| Place x on the stack. The value of x is that given
| when name was created, until the phrase x TO name
| is executed, causing a new value of x to be assigned
| to name.
For example:
123 value foo
' foo ( xt )
\ Executing of this xt shall place 123 on the stack
\ regardless of STATE
On 10/1/22 05:12, Ruvim wrote:
...
The actual problem is that your implementation is not
standard-compliant. Namely, the words defined by this VALUE have
STATE-dependent execution semantics (according to the does-part),
while the standard doesn't specify that [2]:
| name Execution:
| ( -- x )
|
| Place x on the stack. The value of x is that given
| when name was created, until the phrase x TO name
| is executed, causing a new value of x to be assigned
| to name.
For example:
123 value foo
' foo ( xt )
\ Executing of this xt shall place 123 on the stack
\ regardless of STATE
Do you mean the following?
Using Gforth's native VALUE
5 value n1
: [execute] execute ; immediate
: test [ ' n1 ] [execute] [ . ] ; \ prints 5 upon Enter in Gforth
while my original implementation gives the following under Gforth
5 value n1
: [execute] execute ; immediate
: test [ ' n1 ] [execute] [ . ] ;
140095166437768
*the terminal*:5:33: error: Control structure mismatch
: test [ ' n1 ] [execute] [ . ] >>>;<<<
Backtrace:
kernel/cond.fs:119:26: 0 $7F6A72A1F1B0 throw
glocals.fs:582:5: 1 $7F6A72A30DD0 ?struc
kernel/comp.fs:781:5: 2 $7F6A72A15B78 ;-hook
Under kForth-64 my original implementation gives
Line 15: VM Error(-4): Stack underflow
: test [ ' n1 ] [execute] [ . ] ;
Zbig <zbigniew2011@gmail.com> writes:
So state-smart words are bad
They are evil! [ertl98]
but data-type-smart words are (still?)
good? ;)
The polymorphic TO is fine. No such problems as with STATE-smartness.
It feels somewhat alien in Forth, though. It took me and many others
a few decades to warm up to it, but in recent years I hear more and
more people sing the praises of value-flavoured words and TO, e.g.,
Joerg Voelker and Nick Nelson (I can give references if there is
demand).
On 2022-10-01 19:13, Krishna Myneni wrote:...
On 10/1/22 05:12, Ruvim wrote:
...123 value foo
' foo ( xt )
\ Executing of this xt shall place 123 on the stack
\ regardless of STATE
Do you mean the following?
Using Gforth's native VALUE
5 value n1
: [execute] execute ; immediate
: test [ ' n1 ] [execute] [ . ] ; \ prints 5 upon Enter in Gforth
Yes, implementations which fail this test case (i.e., don't print 5) are incorrect.
: value \ n -- ; ??? -- ??? ; 6.2.2405
\ *G Create a variable with an initial value. When the *\fo{VALUE}'s
\ ** name is referenced, the value is returned. Precede the name
\ ** with *\fo{TO} or *\fo{->} to store to it. Precede the name
\ ** with *\fo{ADDR} to get the address of the data. The full list
\ ** of operators is displayed by *\fo{.OPERATORS ( -- )}.
\ *E 5 VALUE FOO \ initial value of FOO is 5
\ ** FOO . \ will give 5
\ ** 6 TO FOO \ new value is 6
\ ** FOO . \ will give 6
\ ** ADDR FOO @ . \ will give 6
create
, ['] valComp, set-compiler
interp>
valInterp
;
INTERP> is like DOES> but specifies only the interpretation behaviour of the child, whereas SET-COMPILER specifies how the child is compiled.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
I still don't get how SET-OPTIMIZER works. Earlier you stated,
"In VFX SET-OPTIMIZER is called SET-COMPILER, which misleads people
into believing that it changes the compilation semantics."
Doesn't SET-OPTIMIZER change the compilation semantics of the words
created by VALUE 2VALUE etc.?
No. SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the >quotation for SET-OPTIMIZER. Then the compilation semantics (behavior)
can be different from that of a word defined without SET-OPTIMIZER.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the
quotation for SET-OPTIMIZER. Then the compilation semantics (behavior)
can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as specified (and, more importantly, as used in most places where
COMPILE, is used).
On 10/2/22 00:00, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:..
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the >>> quotation for SET-OPTIMIZER. Then the compilation semantics (behavior)
can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as
specified (and, more importantly, as used in most places where
COMPILE, is used).
Clearly there is a lot to think about here. Given that SET-COMPSEM takes
a new compilation xt and sets it as the new compilation semantics for
the last definition, the following does not work
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-compsem ;
In the above, SET-OPTIMIZER is replaced by SET-COMPSEM.
Is there a way to place the xt of the last
definition on the stack, so that SET-COMPSEM can be used in the
definition of VALUE?
On 10/2/22 00:00, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:..
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the >>> quotation for SET-OPTIMIZER. Then the compilation semantics (behavior)
can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as
specified (and, more importantly, as used in most places where
COMPILE, is used).
Clearly there is a lot to think about here. Given that SET-COMPSEM takes
a new compilation xt and sets it as the new compilation semantics for
the last definition, the following does not work
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-compsem ;
In the above, SET-OPTIMIZER is replaced by SET-COMPSEM.
The reason that
the new definition fails (in compilation mode) appears to be that there
is no xt for the value on the stack for the new compilation semantics to operate on with >BODY.
Is there a way to place the xt of the last
definition on the stack, so that SET-COMPSEM can be used in the
definition of VALUE?
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
On 10/2/22 00:00, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:..
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the >>>> quotation for SET-OPTIMIZER. Then the compilation semantics (behavior) >>>> can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as
specified (and, more importantly, as used in most places where
COMPILE, is used).
Clearly there is a lot to think about here. Given that SET-COMPSEM takes
a new compilation xt and sets it as the new compilation semantics for
the last definition, the following does not work
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-compsem ;
In the above, SET-OPTIMIZER is replaced by SET-COMPSEM.
Why? SET-OPTIMIZER was appropriate here: values have default
compilation semantics. And the implementation was correct.
Is there a way to place the xt of the last
definition on the stack, so that SET-COMPSEM can be used in the
definition of VALUE?
You can use Gforth's closures to pass a stack item from closure
construction time to closure run-time.
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;] set-compsem ;
In the following, let's assume you have a word defined with
0 broken-value n2
BROKEN-VALUE and the words created by it have the following
disadvantages compared to the VALUE that uses SET-OPTIMIZER:
* [COMPILE] N2 has the same effect as POSTPONE N2, not the same effect
as just compiling N2, which a standard value would have. The reason
is that [COMPILE] thinks it has non-default compilation semantics;
if you want to stick with default compilation semantics, don't use
SET-COMPSEM! This is the reason why I called this word
BROKEN-VALUE.
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
On 10/2/22 11:14, Anton Ertl wrote:
Krishna Myneni <krishna...@ccreweb.org> writes:
On 10/2/22 00:00, Anton Ertl wrote:
Krishna Myneni <krishna...@ccreweb.org> writes:..
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence inside the >>>> quotation for SET-OPTIMIZER. Then the compilation semantics (behavior) >>>> can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as
specified (and, more importantly, as used in most places where
COMPILE, is used).
Clearly there is a lot to think about here. Given that SET-COMPSEM takes >> a new compilation xt and sets it as the new compilation semantics for
the last definition, the following does not work
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-compsem ;
In the above, SET-OPTIMIZER is replaced by SET-COMPSEM.
Why? SET-OPTIMIZER was appropriate here: values have default
compilation semantics. And the implementation was correct.
Is there a way to place the xt of the last
definition on the stack, so that SET-COMPSEM can be used in the
definition of VALUE?
You can use Gforth's closures to pass a stack item from closure construction time to closure run-time.
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;] set-compsem ;
Yes, this is what I want.
In the following, let's assume you have a word defined with
0 broken-value n2
BROKEN-VALUE and the words created by it have the following
disadvantages compared to the VALUE that uses SET-OPTIMIZER:
* [COMPILE] N2 has the same effect as POSTPONE N2, not the same effect
as just compiling N2, which a standard value would have. The reason
is that [COMPILE] thinks it has non-default compilation semantics;
if you want to stick with default compilation semantics, don't use SET-COMPSEM! This is the reason why I called this word
BROKEN-VALUE.
[COMPILE] is obsolete and need not be discussed. It used to exist in
kForth and has been removed.
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
This is a more fundamental issue because "COMPILE," is specified to work
with an xt. On a system which supports name tokens, "COMPILE," can still
work with the xt (performing LITERAL and compiling EXECUTE) but it
points to the absence of a compilation word which takes an nt as an
argument and performs LITERAL and compiles NAME>COMPILE and EXECUTE .
Then it will be optimized.
In short, I think using SET-COMPSEMP is a more transparent way of
achieving optimization and your BROKEN-VALUE definition would be my
preferred way to go about it. On a dual token system (one which provides
a reference to interpretation semantics and a separate reference to compilation semantics) I want to avoid thinking about whether the
compilation semantics are default or non-default. There is only
"compilation semantics" for a word, at any given instance in time. The
system provides compilation semantics for the word upon definition but
it may be changed later, if desired. Similarly, for words which CREATE
other words, there should be a mechanism for setting the compilation semantics of the created words immediately after creation, if desired.
On 10/2/22 11:14, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
On 10/2/22 00:00, Anton Ertl wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:..
On 10/1/22 02:06, Anton Ertl wrote:
SET-OPTIMIZER sets the implementation of COMPILE, ( xt -- ) for
the current word. A correct implementation of COMPILE, does not
change the semantics in any way, only the implementation of the
semantics. So if you instead do
[: postpone literal postpone execute ;] set-optimizer
the behaviour stays the same.
I not seeing the difference. I can put any arbitrary sequence
inside the
quotation for SET-OPTIMIZER. Then the compilation semantics (behavior) >>>>> can be different from that of a word defined without SET-OPTIMIZER.
Yes, you can shoot yourself in the foot with SET-OPTIMIZER. This is
Forth. But once you have done that, COMPILE, does no longer work as
specified (and, more importantly, as used in most places where
COMPILE, is used).
Clearly there is a lot to think about here. Given that SET-COMPSEM takes >>> a new compilation xt and sets it as the new compilation semantics for
the last definition, the following does not work
: value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
[: >body cell+ postpone literal postpone @ ;] set-compsem ;
In the above, SET-OPTIMIZER is replaced by SET-COMPSEM.
Why? SET-OPTIMIZER was appropriate here: values have default
compilation semantics. And the implementation was correct.
Is there a way to place the xt of the last
definition on the stack, so that SET-COMPSEM can be used in the
definition of VALUE?
You can use Gforth's closures to pass a stack item from closure
construction time to closure run-time.
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;]
set-compsem ;
Yes, this is what I want.
In the following, let's assume you have a word defined with
0 broken-value n2
BROKEN-VALUE and the words created by it have the following
disadvantages compared to the VALUE that uses SET-OPTIMIZER:
* [COMPILE] N2 has the same effect as POSTPONE N2, not the same effect
as just compiling N2, which a standard value would have. The reason >> is that [COMPILE] thinks it has non-default compilation semantics;
if you want to stick with default compilation semantics, don't use
SET-COMPSEM! This is the reason why I called this word
BROKEN-VALUE.
[COMPILE] is obsolete and need not be discussed. It used to exist in
kForth and has been removed.
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
This is a more fundamental issue because "COMPILE," is specified to work
with an xt. On a system which supports name tokens, "COMPILE," can still
work with the xt (performing LITERAL and compiling EXECUTE) but it
points to the absence of a compilation word which takes an nt as an
argument and performs LITERAL and compiles NAME>COMPILE and EXECUTE .
Then it will be optimized.
In short, I think using SET-COMPSEMP is a more transparent way of
achieving optimization and your BROKEN-VALUE definition would be my
preferred way to go about it.
On a dual token system (one which provides
a reference to interpretation semantics and a separate reference to compilation semantics) I want to avoid thinking about whether the
compilation semantics are default or non-default. There is only
"compilation semantics" for a word, at any given instance in time. The
system provides compilation semantics for the word upon definition but
it may be changed later, if desired. Similarly, for words which CREATE
other words, there should be a mechanism for setting the compilation semantics of the created words immediately after creation, if desired.
But the notion of anonymous definition and execution semantics are
essential in Forth. It's a rock other conceptions are based on.
--
Ruvim
In article <theadt$24khr$1@dont-email.me>,
Ruvim <ruvim.pinka@gmail.com> wrote:
<SNIP>
But the notion of anonymous definition and execution semantics are
essential in Forth. It's a rock other conceptions are based on.
No it isn't. Anything accomplished by an anonymous definition can be accomplished by a definition that has a name and can be properly
found in the dictionary.
"It's a rock other conceptions are based on."
If only that were true.
A redesigned forth from the ground up looks like lucky7.
In lucky7 the fundamental construction is
{ ... } that leaves a behaviour token ("xt" not a "nt")
than can be run ("execute").
Krishna Myneni<krishna.myneni@ccreweb.org> writes:
On 9/30/22 04:30, albert wrote:There is no such rule. Forth-94 and 2012 describe TO as parsing
There was a discussion about the original ANSI 93 rule
that "TO must parse".
words, allowing the implementation of a parsing TO. But, as you
mention, there is no standard program that could determine if TO does
not parse, so a standard system can also have a non-parsing TO.
On 9/29/22 02:24, minf...@arcor.de wrote:
Krishna Myneni schrieb am Donnerstag, 29. September 2022 um 02:43:10
UTC+2:
On 9/28/22 19:39, Krishna Myneni wrote:
------
: NONDEFERRED ;
SYNONYM
The above line should have been
SYNONYM A@ @
--
Thanks for posting this!
It is refreshing to read some substantial contribution again
here in c.l.f., instead of all those silly rantings of the last months.
I was only wondering if your idea could be extended to +TO.
Yes, it can; however, if you need to use +TO my advice would be to not
use a VALUE (or FVALUE or other extended VALUE) but go back to
VARIABLEs. One can use of +! , F+! (not currently standard, but
necessary), etc. with corresponding variables. A drawback of TO and extensions such as +TO is that various Forth operations such as '
(tick), ['], POSTPONE, etc. on them results in an ambiguous condition in standard Forth.
On 2022-10-03 01:08, Krishna Myneni wrote:
This is a more fundamental issue because "COMPILE," is specified to
work with an xt. On a system which supports name tokens, "COMPILE,"
can still work with the xt (performing LITERAL and compiling EXECUTE)
but it points to the absence of a compilation word which takes an nt
as an argument and performs LITERAL and compiles NAME>COMPILE and
EXECUTE . Then it will be optimized.
Taking into account that "compile," can be implemented as:
: compile, ( xt -- ) postpone literal postpone execute ;
It seems you assume that the following phrases are equivalent for an
ordinary word (for which xt and nt are defined):
postpone literal postpone execute
\ run-time: ( xt -- )
postpone literal postpone name>compile postpone execute
\ run-time: ( nt -- )
But they are not equivalent.
— The first phrase in run-time *performs* the compilation semantics for
the word (and later "execute" executes the word) .
— The second phrase in run-time *appends* the compilation semantics for
the word to the current definition (and later "execute" executes the compilation semantics for the word).
In short, I think using SET-COMPSEMP is a more transparent way of
achieving optimization and your BROKEN-VALUE definition would be my
preferred way to go about it.
Probably you actually thought about something like "compile-nt"
: compile-nt ( i*x nt -- j*x ) name>compile execute ;
But this word cannot replace "compile," due to the following reasons:
1. There is a common standard-compliant pattern to compile an ordinary
word:
['] foo compile,
And this pattern should remain valid.
2. Anonymous definitions don't have associated nt (name token), and the
only way to compile them is to use "compile,".
BTW, in my system I associate a custom compilation procedure not with
nt, but with xt. So, an optimized compiler can be specified for an
anonymous definition too.
Also, it's less confusing, since the notion of compilation semantics is
not applicable to execution tokens. And when you set a compiler for xt,
you cannot think like you define compilation semantics by that for some
word at all.
On a dual token system (one which provides a reference to
interpretation semantics and a separate reference to compilation
semantics) I want to avoid thinking about whether the compilation
semantics are default or non-default. There is only "compilation
semantics" for a word, at any given instance in time. The system
provides compilation semantics for the word upon definition but it may
be changed later, if desired. Similarly, for words which CREATE other
words, there should be a mechanism for setting the compilation
semantics of the created words immediately after creation, if desired.
In such a case you have to eliminate execution tokens, "execute" and "compile," from your system (i.e., make them inaccessible for a user).
But the notion of anonymous definition and execution semantics are
essential in Forth. It's a rock other conceptions are based on.
On a dual token system (one which provides a reference to
interpretation semantics and a separate reference to compilation
semantics) I want to avoid thinking about whether the compilation
semantics are default or non-default. There is only "compilation
semantics" for a word, at any given instance in time. The system
provides compilation semantics for the word upon definition but it may
be changed later, if desired. Similarly, for words which CREATE other
words, there should be a mechanism for setting the compilation
semantics of the created words immediately after creation, if desired.
In such a case you have to eliminate execution tokens, "execute" and "compile," from your system (i.e., make them inaccessible for a user).
Probably you actually thought about something like "compile-nt"
: compile-nt ( i*x nt -- j*x ) name>compile execute ;
But this word cannot replace "compile," due to the following reasons:
1. There is a common standard-compliant pattern to compile an ordinary
word:
['] foo compile,
And this pattern should remain valid.
2. Anonymous definitions don't have associated nt (name token), and the
only way to compile them is to use "compile,".
BTW, in my system I associate a custom compilation procedure not with
nt, but with xt. So, an optimized compiler can be specified for an
anonymous definition too.
Also, it's less confusing, since the notion of compilation semantics is
not applicable to execution tokens. And when you set a compiler for xt,
you cannot think like you define compilation semantics by that for some
word at all.
It seems you assume that the following phrases are equivalent for an
ordinary word (for which xt and nt are defined):
postpone literal postpone execute
\ run-time: ( xt -- )
postpone literal postpone name>compile postpone execute
\ run-time: ( nt -- )
But they are not equivalent.
— The first phrase in run-time *performs* the compilation semantics for
the word (and later "execute" executes the word) .
— The second phrase in run-time *appends* the compilation semantics for
the word to the current definition (and later "execute" executes the compilation semantics for the word).
Krishna Myneni schrieb am Sonntag, 2. Oktober 2022 um 23:08:43 UTC+2:..
In short, I think using SET-COMPSEMP is a more transparent way of
achieving optimization and your BROKEN-VALUE definition would be my
preferred way to go about it. On a dual token system (one which provides
a reference to interpretation semantics and a separate reference to
compilation semantics) I want to avoid thinking about whether the
compilation semantics are default or non-default. There is only
"compilation semantics" for a word, at any given instance in time. The
system provides compilation semantics for the word upon definition but
it may be changed later, if desired. Similarly, for words which CREATE
other words, there should be a mechanism for setting the compilation
semantics of the created words immediately after creation, if desired.
True.
An admttedly not very important and very personal side observation:
I find all those differing syntaxes confusing and more often than not plain ugly.
In my dual-xt system use just these words
COMPILES> (aligned "esthetically" to DOES>)
COMPILES (aligned "esthetically" to IS)
IMMEDIATE
COMPILE-ONLY
to control the compilation.
Usage:
: DUALWORD <compilation semantic> COMPILES> <execution sematic> ;
to define a dual-xt word in one go
:NONAME <compilation semantic> ; COMPILES OTHERWORD
(or similarly through ticking) to add/overwrite OTHERWORD's
compilation-xt in its header
IMMEDIATE
to make last word's compilation-xt and execution-xt identical in its header
COMPILE-ONLY
to move execution-xt to compilation-xt in last word's header for normal words (resp. set execution-xt to zero when last word is already immediate).
Of course the text interpreter is adapted to check the presence of both xt's in the header of found names. Up to now this simple scheme has served me well, but perhaps only because I don't play funny things with the Forth compiler
like others seem to do.
On 29/09/2022 11:20, Krishna Myneni wrote:
On 9/29/22 02:24, minf...@arcor.de wrote:
I was only wondering if your idea could be extended to +TO.
Yes, it can; however, if you need to use +TO my advice would be to not
use a VALUE (or FVALUE or other extended VALUE) but go back to
VARIABLEs. One can use of +! , F+! (not currently standard, but
necessary), etc. with corresponding variables. A drawback of TO and
extensions such as +TO is that various Forth operations such as '
(tick), ['], POSTPONE, etc. on them results in an ambiguous condition
in standard Forth.
If I define +TO as (using standard Forth):
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
which given
+to x
on a value x evaluates
x + to x
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
On 10/3/22 04:07, Anders Koburg wrote:
An admttedly not very important and very personal side observation:
I find all those differing syntaxes confusing and more often than not
plain ugly.
In my dual-xt system use just these words
COMPILES> (aligned "esthetically" to DOES>)
COMPILES (aligned "esthetically" to IS)
IMMEDIATE
COMPILE-ONLY
to control the compilation.
Usage:
: DUALWORD <compilation semantic> COMPILES> <execution sematic> ;
to define a dual-xt word in one go
:NONAME <compilation semantic> ; COMPILES OTHERWORD
(or similarly through ticking) to add/overwrite OTHERWORD's
compilation-xt in its header
IMMEDIATE
to make last word's compilation-xt and execution-xt identical in its
header
COMPILE-ONLY
to move execution-xt to compilation-xt in last word's header for
normal words
(resp. set execution-xt to zero when last word is already immediate).
Of course the text interpreter is adapted to check the presence of
both xt's
in the header of found names. Up to now this simple scheme has served me
well, but perhaps only because I don't play funny things with the
Forth compiler
like others seem to do.
I like your names. They are more aesthetic. I suggest you use "interpretation-xt" in place of "execution-xt". Both xt's are execution tokens.
The examples given where state-smart words can fail are a bit contrived
for simplicity; however, when you try to do non-trivial things, you want
to be able to analyze the behavior of the code, and always knowing the compilation and interpretation behavior of words will help to predict
what the code will do. Most routine coding is trivial to understand.
--
Krishna
On 04/10/2022 22:53, Ruvim wrote:
On 2022-10-04 01:10, Gerry Jackson wrote:
On 29/09/2022 11:20, Krishna Myneni wrote:
On 9/29/22 02:24, minf...@arcor.de wrote:
I was only wondering if your idea could be extended to +TO.
Yes, it can; however, if you need to use +TO my advice would be to
not use a VALUE (or FVALUE or other extended VALUE) but go back to
VARIABLEs. One can use of +! , F+! (not currently standard, but
necessary), etc. with corresponding variables. A drawback of TO and
extensions such as +TO is that various Forth operations such as '
(tick), ['], POSTPONE, etc. on them results in an ambiguous
condition in standard Forth.
If I define +TO as (using standard Forth):
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
which given
+to x
on a value x evaluates
x + to x
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
Having an opaque implementation for "+to", Tick should not be applied
to "+to" in a standard program while execution semantics are not
specified for "+to" in the documentation.
Sorry, I thought the semantics of +TO was well understood so
documentation was unnecessary in a c.l.f discussion
"postpone" may be applied to "+to" in any case. But the behavior of
the containing definition in interpretation state is ambiguous if the
system provides not fully compliant "postpone".
A test case:
: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
If this test fails, the system /effectively/ imposes an environmental
restriction: a program should not start performing compilation
semantics in interpretation state.
Yes my system and others failed test-x. To make this work something like
a compile only word [+TO] needs to be defined
On 2022-10-05 16:17, Gerry Jackson wrote:
On 04/10/2022 22:53, Ruvim wrote:
On 2022-10-04 01:10, Gerry Jackson wrote:
On 29/09/2022 11:20, Krishna Myneni wrote:
On 9/29/22 02:24, minf...@arcor.de wrote:
I was only wondering if your idea could be extended to +TO.
Yes, it can; however, if you need to use +TO my advice would be to
not use a VALUE (or FVALUE or other extended VALUE) but go back to
VARIABLEs. One can use of +! , F+! (not currently standard, but
necessary), etc. with corresponding variables. A drawback of TO and
extensions such as +TO is that various Forth operations such as '
(tick), ['], POSTPONE, etc. on them results in an ambiguous
condition in standard Forth.
If I define +TO as (using standard Forth):
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
which given
+to x
on a value x evaluates
x + to x
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
Having an opaque implementation for "+to", Tick should not be applied
to "+to" in a standard program while execution semantics are not
specified for "+to" in the documentation.
Sorry, I thought the semantics of +TO was well understood soWhat are well understood are the interpretation semantics and
documentation was unnecessary in a c.l.f discussion
compilation semantics for "+to", but not execution semantics.
If the phrase:
' +to
returns an xt, this xt identifies some execution semantics. And these execution semantics may vary, if you don't specify it in a documentation/standard/etc. (NB: I consider a case of opaque implementations).
"postpone" may be applied to "+to" in any case. But the behavior of
the containing definition in interpretation state is ambiguous if the
system provides not fully compliant "postpone".
A test case:
: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
If this test fails, the system /effectively/ imposes an environmental
restriction: a program should not start performing compilation
semantics in interpretation state.
Yes my system and others failed test-x. To make this work something likeTo make this work something like a fully compliant "postpone" should be defined.
a compile only word [+TO] needs to be defined
See: https://github.com/ForthHub/discussion/discussions/105
On 2022-10-04 01:10, Gerry Jackson wrote:
On 29/09/2022 11:20, Krishna Myneni wrote:
On 9/29/22 02:24, minf...@arcor.de wrote:
I was only wondering if your idea could be extended to +TO.
Yes, it can; however, if you need to use +TO my advice would be to
not use a VALUE (or FVALUE or other extended VALUE) but go back to
VARIABLEs. One can use of +! , F+! (not currently standard, but
necessary), etc. with corresponding variables. A drawback of TO and
extensions such as +TO is that various Forth operations such as '
(tick), ['], POSTPONE, etc. on them results in an ambiguous condition
in standard Forth.
If I define +TO as (using standard Forth):
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
which given
+to x
on a value x evaluates
x + to x
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
Having an opaque implementation for "+to", Tick should not be applied to "+to" in a standard program while execution semantics are not specified
for "+to" in the documentation.
"postpone" may be applied to "+to" in any case. But the behavior of the containing definition in interpretation state is ambiguous if the system provides not fully compliant "postpone".
A test case:
: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
If this test fails, the system /effectively/ imposes an environmental restriction: a program should not start performing compilation semantics
in interpretation state.
--
Ruvim
On 10/6/22 08:39, Krishna Myneni wrote:
On 10/2/22 11:14, Anton Ertl wrote:..
..
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;]
set-compsem ;
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
I see that Gforth provides a word to convert an xt to an nt with the
word XT>NAME. Therefore, you should be able to obtain proper
compilation of N2 with "COMPILE," simply with
: compile-name ( nt -- ) name>compile execute ;
: compile, ( xt -- ) xt>name compile-name ;
This should make SET-OPTIMIZER unnecessary since the compilation
semantics set with SET-COMPSEM will then be used by the new
"COMPILE,". The redefinition of "COMPILE," will still work on a
single-xt system.
Spoke too soon. The above is not a good idea, since COMPILE, will no
longer simply compile the semantics of xt without translation. There is
still a need for the standard behavior of COMPILE, .
On 10/2/22 11:14, Anton Ertl wrote:..
..
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;]
set-compsem ;
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
I see that Gforth provides a word to convert an xt to an nt with the
word XT>NAME. Therefore, you should be able to obtain proper compilation
of N2 with "COMPILE," simply with
: compile-name ( nt -- ) name>compile execute ;
: compile, ( xt -- ) xt>name compile-name ;
This should make SET-OPTIMIZER unnecessary since the compilation
semantics set with SET-COMPSEM will then be used by the new "COMPILE,".
The redefinition of "COMPILE," will still work on a single-xt system.
: broken-value ( n "name" -- )
[ s" !" find-name ] literal 1 cells xVALUE
[: does> cell+ @ ;] execute
lastxt >body cell+ [n:d postpone literal postpone @ ;] set-compsem ;
In the following, let's assume you have a word defined with
0 broken-value n2
BROKEN-VALUE and the words created by it have the following
disadvantages compared to the VALUE that uses SET-OPTIMIZER:
* COMPILE,ing the xt of N2 now does not optimize. The result is
correct, but not as fast as what you get with the SET-OPTIMIZER
variant.
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics, interpretation or compilation, can be specified for compilation.
On 6 Oct 2022 at 16:13:56 CEST, "Krishna Myneni" <krishna.myneni@ccreweb.org> wrote:
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics,
interpretation or compilation, can be specified for compilation.
I cannot resist a chuckle when I find that in the current gxxxxx the headers have been changed so that nt=xt.
All that effort and people are back where we started. "Simplify and add lightness" is always a good engineering maxim.
On 10/7/22 06:35, Stephen Pelc wrote:
On 6 Oct 2022 at 16:13:56 CEST, "Krishna Myneni" <krishna...@ccreweb.org> wrote:
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics, >> interpretation or compilation, can be specified for compilation.
I cannot resist a chuckle when I find that in the current gxxxxx the headers
have been changed so that nt=xt.
All that effort and people are back where we started. "Simplify and add lightness" is always a good engineering maxim.
Gforth's nt = xt-interp. While Gforth provides for dual semantics words, it's not entirely clear from their paper [1] that xt-comp (referencing
the compilation semantics) is stored separately for all words. It
appears that xt-comp may be computed in some cases.
A simple header for a dual-xt system would only require storage in the header for another execution token (xt-comp), compared to the single-xt system. Also, the precedence flag can be remove from the dictionary header.
A dual-xt system does not need a complex header, although the Gforth 1.0 header appears to be quite complex. I haven't digested this paper to understand the reasons for its complexity, but I suspect they don't have
to do with the fact that it supports words with dual semantics and more likely the reasons have to do with optimization.
--
Krishna
Refs.
1. B. Paysan and M. A. Ertl, "The new Gforth Header", https://publik.tuwien.ac.at/files/publik_287599.pdf
Thank you all for an interesting discussion and thread. I have grown very frustrated over time with the constant bickering and occasionally consider unsubscribing from this group. But it is discussions like this that continue to make comp.lang.forthworth following.
I just wanted to stick in my totally unrelated 2 cents worth.
On Friday, October 7, 2022 at 7:12:22 AM UTC-7, Krishna Myneni wrote:..
On 10/7/22 06:35, Stephen Pelc wrote:
On 6 Oct 2022 at 16:13:56 CEST, "Krishna Myneni" <krishna...@ccreweb.org> >>> wrote:Gforth's nt = xt-interp. While Gforth provides for dual semantics words,
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics, >>>> interpretation or compilation, can be specified for compilation.
I cannot resist a chuckle when I find that in the current gxxxxx the headers
have been changed so that nt=xt.
All that effort and people are back where we started. "Simplify and add
lightness" is always a good engineering maxim.
it's not entirely clear from their paper [1] that xt-comp (referencing
the compilation semantics) is stored separately for all words. It
appears that xt-comp may be computed in some cases.
Thank you all for an interesting discussion and thread. I have grown very frustrated over time with the constant bickering and occasionally consider unsubscribing from this group. But it is discussions like this that continue to make comp.lang.forthworth following.
I just wanted to stick in my totally unrelated 2 cents worth.
r...@braithwaites.net schrieb am Freitag, 7. Oktober 2022 um 20:30:26 UTC+2:worth following.
Thank you all for an interesting discussion and thread. I have grown very frustrated over time with the constant bickering and occasionally consider unsubscribing from this group. But it is discussions like this that continue to make comp.lang.forth
I just wanted to stick in my totally unrelated 2 cents worth.
You're not alone with this opinion. While some "participants" here behave like Statler
and Waldorf from Muppet show, just don't feed them. And perhaps you could start
an interesting discussion, there are some really smart and experienced guys in this
forum.
On 6 Oct 2022 at 16:13:56 CEST, "Krishna Myneni" <krishna.myneni@ccreweb.org> >wrote:
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics,
interpretation or compilation, can be specified for compilation.
I cannot resist a chuckle when I find that in the current gxxxxx the headers >have been changed so that nt=xt.
All that effort and people are back where we started. "Simplify and add >lightness" is always a good engineering maxim.
Stephen
Actually, these methods ("SET-COMPSEM" and "SET-OPTIMIZER") are mutual >exclusive for a word
The reason that
the new definition fails (in compilation mode) appears to be that there
is no xt for the value on the stack for the new compilation semantics to
operate on with >BODY.
It's absent by design, since this xt is not required on implied use cases.
See also the example in [1]:
\ :noname ." compiling" ;
\ : foo ." interpreting" ; set-compsem
Take into account that the anonymous definition intended to perform the >compilation semantics for "foo" is defined *before* "foo".
It's because "set-compsem" changes the last defined word, and an
anonymous definition is also a word in Gforth (1)
A closure (namely, a partial application [2]) could be used for that,
but the limitation (1) makes it more difficult, since a generated
anonymous definition becomes last definition.
[COMPILE] is obsolete and need not be discussed. It used to exist in
kForth and has been removed.
In short, I think using SET-COMPSEMP is a more transparent way of
achieving optimization and your BROKEN-VALUE definition would be my
preferred way to go about it.
On a dual token system (one which provides
a reference to interpretation semantics and a separate reference to >compilation semantics) I want to avoid thinking about whether the
compilation semantics are default or non-default.
On 2022-09-29 21:43, Anton Ertl wrote:
Zbig <zbigniew2011@gmail.com> writes:
So state-smart words are bad
They are evil! [ertl98]
In this regard the paper shows that it's incorrect to implement an
ordinary word as an immediate word. So, it's not just evil, it's a mistake.
But concerning 's"' (and other combined words) the paper only says (in
the section 3, on page 3):
| This definition behaves correctly as long as it
| is only processed by the text interpreter,
| but it fails with ', postpone, etc.,
| as discussed in Section 2.
This reasoning is wrong:
1. actually, it does not fail with ' (Tick);
2. if it fails with "postpone", then a problem is in "postpone", and
the problem should be corrected in "postpone".
I explained [1] why it doesn't fail with Tick:
It's obvious that in the general case, performing execution semantics in >compilation state may be inequivalent to performing these execution
semantics in interpretation state.
And we don't have any ground to say
that they should be equivalent in the case of the s" word, since the >execution semantics for s" are not specified by the standard.
An alternative to the TO-based approach is to just define two words:
getter and setter. So, instead of a phrase "to foo" you use a single
word "to-foo". I mean a real ordinary word, so "' to-foo execute"
performs execution semantics of "to-foo". The word "to-foo" is created >automatically along with "foo".
If I define +TO as (using standard Forth):
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
' ['] and POSTPONE can be applied to +TO.
On 01/10/2022 09:45, Anton Ertl wrote:
there is no standard program that could determine if TO does
not parse, so a standard system can also have a non-parsing TO.
But a non-standard program may detect a non-parsing TO e.g.
where TO sets a flag that a following value tests to return or change
its value.
\ --------------------
VFX Forth 64 for Windows x64
© MicroProcessor Engineering Ltd, 1998-2022
Version: 5.20 [build 4077]
Build date: 1 August 2022
Free dictionary = 6966470 bytes [6803kb]
0 value x x . 0 ok
123 to to x x . 123 ok
234 to to to to x x . 234 ok
345 to ok-1
x x . 345 ok
\ ----------------------------
On 04/10/2022 22:53, Ruvim wrote:...
On 2022-10-04 01:10, Gerry Jackson wrote:
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
...: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
Yes my system and others failed test-x.
Gerry Jackson <do-not-use@swldwa.uk> writes:
On 04/10/2022 22:53, Ruvim wrote:...
On 2022-10-04 01:10, Gerry Jackson wrote:
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
Forgot to comment on this earlier, but this posting shows why you may
want to document POSTPONE +TO as ambiguous (and also all the other cases).
...: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
Yes my system and others failed test-x.
That's because +TO is state-smart (with the state dependence coming
from EVALUATE).
On 10/6/22 08:51, Krishna Myneni wrote:
On 10/6/22 08:39, Krishna Myneni wrote:
: compile-name ( nt -- ) name>compile execute ;
: compile, ( xt -- ) xt>name compile-name ;
This should make SET-OPTIMIZER unnecessary since the compilation
semantics set with SET-COMPSEM will then be used by the new
"COMPILE,". The redefinition of "COMPILE," will still work on a
single-xt system.
Spoke too soon. The above is not a good idea, since COMPILE, will no
longer simply compile the semantics of xt without translation. There is
still a need for the standard behavior of COMPILE, .
Also, SET-OPTIMIZER is not a good idea for the same reason. It bypasses
what is intended by "COMPILE," which is simply to compile the execution >semantics represented by xt .
If SET-OPTIMIZER is used to alter the
compilation semantics of a word
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics, >interpretation or compilation, can be specified for compilation.
On 10/6/22 08:39, Krishna Myneni wrote:
I see that Gforth provides a word to convert an xt to an nt with the
word XT>NAME.
While Gforth provides for dual semantics words,
it's not entirely clear from their paper [1] that xt-comp (referencing
the compilation semantics) is stored separately for all words.
A simple header for a dual-xt system would only require storage in the
header for another execution token (xt-comp), compared to the single-xt >system. Also, the precedence flag can be remove from the dictionary header.
A dual-xt system does not need a complex header, although the Gforth 1.0 >header appears to be quite complex. I haven't digested this paper to >understand the reasons for its complexity, but I suspect they don't have
to do with the fact that it supports words with dual semantics and more >likely the reasons have to do with optimization.
On 6 Oct 2022 at 16:13:56 CEST, "Krishna Myneni" <krishna.myneni@ccreweb.org> >wrote:
The cleaner solution, in my opinion, would be to use nt-based
compilation when dealing with named words. Then the explicit semantics,
interpretation or compilation, can be specified for compilation.
I cannot resist a chuckle when I find that in the current gxxxxx the headers >have been changed so that nt=xt.
All that effort and people are back where we started.
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
the Gforth 1.0
header appears to be quite complex. I haven't digested this paper to >>understand the reasons for its complexity, but I suspect they don't have
to do with the fact that it supports words with dual semantics and more >>likely the reasons have to do with optimization.
It has to do with all the many requirements we now have: synonyms, >dual-semantics words, optimization, nameless words, TO, DOES>, >defer-flavoured words. The result is quite versatile; as for the
complexity, I doubt that you can satisfy the requirements with less >complexity (and it's actually not particularly complex). Of course,
some might want to get rid of some requirements.
On 2022-10-09 08:19, Anton Ertl wrote:
Gerry Jackson <do-not-use@swldwa.uk> writes:
On 04/10/2022 22:53, Ruvim wrote:...
On 2022-10-04 01:10, Gerry Jackson wrote:
: +to ( n "name" -- )
parse-name 2>r ( -- n ) ( R: -- ca u )
2r@ s" + to " 2r@
<# holds holds holds 2r> #> evaluate
; immediate
' ['] and POSTPONE can be applied to +TO. It may need special
compilation semantics for some cases but that's beside the point.
Forgot to comment on this earlier, but this posting shows why you may
want to document POSTPONE +TO as ambiguous (and also all the other cases). >>
...: compiling(+to) postpone +to ;
0 value x
: test-x 10 [ compiling(+to) x ] x ;
x . test-x . \ should print "0 10"
Yes my system and others failed test-x.
That's because +TO is state-smart (with the state dependence coming
from EVALUATE).
NB: if the system provides a full-compliant implementation for
"postpone" then this "+to" is not state-smart [1]
[1] Anton Ertl, Re: WL-TOOLS and ?IMMEDIATE, 2019-09-21Z >news://2019Sep21.164152@mips.complang.tuwien.ac.at >https://groups.google.com/g/comp.lang.forth/c/wYqHc5hqVjQ/m/CSVN_agwBAAJ
| So if POSTPONE eliminates this STATE-dependence,
| the word is not STATE-smart.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 475 |
Nodes: | 16 (2 / 14) |
Uptime: | 22:48:59 |
Calls: | 9,488 |
Calls today: | 7 |
Files: | 13,617 |
Messages: | 6,121,103 |