Digest #157 2021-07-15

Contributions

[205] 2021-07-14 17:47:02 ruv wrote:

requestClarification - Why "[" is specified using immediacy?

An interesting thing that the word [ is the only immediate word for which interpretation semantics are undefined.

What is a rationale that this word is specified as an immediate word?

It seems, the specification can be simplified by removing the Execution section and making the Compilation section as:

Compilation:

( -- )

Enter interpretation state.

Replies

[r701] 2021-06-28 07:00:03 AntonErtl replies:

comment - Mistake in implementation?

You are right. This should be fixed.


[r702] 2021-06-28 08:12:15 ruv replies:

proposal - The value of STATE should be restored

Simply redefining CATCH/THROW would be problematic, of course, given that previous code might already have the older definitions baked in,

It's enough to redefine catch. And it isn't problematic at all, since use of catch by the system is not detectable by a program.

For example, you can restore base in your program:

: catch ( i*x xt -- j*x ior ) base @ >r catch dup if r> base ! exit then rdrop ;

(NB: the system is non standard after that).

Restoring state doesn't have much sense in a standard program at the moment, since in any case, if compilation was broken, the program cannot create a new definition due to an ambiguous condition, and cannot complete the current definition since the control-flow stack is cleared.

OTOH, saving and restoring (or releasing) some state/resource in every catch is overhead. A better way, as Anton pointed out, is to use a specific save/restore in the places where it is required only.


[r703] 2021-07-01 10:37:45 ruv replies:

referenceImplementation - Portable implementation for SYNONYM

I think, the standard should restrict the systems in such a way that it's impossible for find to return n value -1 in interpretation state for R-related words.

Actually, in a plausible system some R-related words can be implemented as ordinary words (and then find can always return n value -1 for them). For example, if a separate R-stack is used, and this stack is not connected to the real internal return stack. And then >r can be even redefined as : >r >r ; (as any ordinary word). And it will work in the most cases. But it will not work in some edge cases!

For example, if execute and compile, are redefined as following:

variable _x
: execute dup >r execute r> _x ! ;

: compile, postpone literal postpone execute ;

and a Forth text interpreter that uses this compile, is applied to:

  : foo 1 >r 2 r> ;  t{ t -> 2 1 }t

then, having ordinary >r and r> words, this test case will fail.

Since foo will be equivalent to:

\ <=> ( the code, generated by "compile," )
  : foo  1  ['] >r   execute                     2  ['] r>   execute                 ;
\ <=> ( substitute "execute" by its definition )
  : foo  1  ['] >r   dup >r execute r> _x !      2  ['] r>   dup >r execute r> _x !  ;
\ <=> ( substitute "execute" by the executed word, and eliminate "dup" )
  : foo  1  ['] >r       >r      >r r> _x !      2  ['] r>       >r      r> r> _x !  ;
\ <=> ( eliminate the ">r r>" pairs )
  : foo  1  ['] >r       >r            _x !      2  ['] r>                  r> _x !  ;
\ <=> ( safely move "['] >r" into another place ) 
  : foo  1                             _x !      2  ['] r>        ['] >r >r r> _x !  ;
\ <=> ( eliminate the ">r r>" pair )
  : foo  1                             _x !      2  ['] r>        ['] >r       _x !  ;
\ <=> ( leave only the effects that are visible for a standard program )
  : foo                                          2  ['] r>                           ;
\ <=> 
  : foo 2  ['] r> ;
\ that is not equivalent to "2 >r 1 r>" 

Hence, it's impossible to hold the expected equivalencies and provide ordinary R-related words in the same time.

So a requirement to hold some equivalencies automatically makes impossible such implementation that find returns n value -1 in interpretation state for some R-related word (NB: the words i, j, unloop, leave are also included).


[r704] 2021-07-03 17:32:21 MatteoVitturi replies:

example - Needs an example of replacing COMPILE

Hello,

POSTPONE 's Interpretation semantics are undefined and [ is an immediate word used to enter interpretation state, this implies that in the example

: foo .... [ POSTPONE THEN ] ....  [ POSTPONE branch <RESOLVE ] ; 

POSTPONE used within square brackets leads to an ambigous condition.

Where am I wrong ?


[r705] 2021-07-05 14:40:42 ruv replies:

example - Needs an example of replacing COMPILE

POSTPONE used within square brackets leads to an ambigous condition. Where am I wrong?

It's wrong to assume that it's a real code. In general, it's a pseudo-code, and just a kind of algebra, when you substitute one expression by another expression according to some rules (and this code fragment is an intermediate step in an algebraic transformation). It's aimed to better understand something or prove.

In some cases, when the certain assumptions are met, such a pseudo-code can be a correct real code too.

According to the standard, a Forth system is allowed to provide implementation-defined interpretation semantics for a word for which the standard undefines interpretation semantics (see A.3.4.3.2).

In this particular case, the assumption is that the interpretation semantics for postpone are to take the word/name in the argument and perform the compilation semantics for it (NB: this assumption was mentioned!). Moreover, if you hold the equivalence of compile, and postpone literal postpone execute, and provide the ordinary compile, word, then these interpretation semantics for postpone are the only possible option.


[r706] 2021-07-07 12:31:02 ruv replies:

requestClarification - Address between runs

The normative part says:

a-addr is the address of the space reserved by BUFFER: when it defined name.

And then a-addr should be a constant even between runs from a saved image (since name is defined only once).

But the rationale says:

hosted systems are permitted to ALLOCATE a buffer.

It means that a-addr can be different on every run from a saved image.

Requiring a-addr to be a constant between runs from an image makes implementations more difficult and provides almost nothing benefits for programs. So I suggest to relax implementations in this regard.

But a formal problem is that it's difficult to specify in the normative part that a-addr may change between runs due to lack of the corresponding model and terminology in the standard.

The irony is that BUFFER: is more demanded by programs that support embedded targets, when programs are often precompiled and saved into an image, but such usage scenario is out of the scope of the standard. And hence the corresponding behavior cannot be formally specified for this word.

Perhaps is should be informally stated in the rationale at least.


[r707] 2021-07-07 12:42:12 ruv replies:

referenceImplementation - Portable implementation for SYNONYM

Corrections for typos.

Please read:

 : foo 1 >r 2 r> ;  t{ t -> 2 1 }t

as:

 : foo 1 >r 2 r> ;  t{ foo -> 2 1 }t

And read:

\ that is not equivalent to "2 >r 1 r>" 

as:

\ that is not equivalent to "1 >r 2 r>"