The accepted proposal for quotations [1] specifies only compilation
semantics for the words "[:" and ";]".
The expected interpretation semantics for "[: ... ;]" are ...
Let's take the definition:
: foo [: 123 . ;] execute ;
There is no a convincing reason why the following lines should not be observationally equivalent:
foo
[: 123 . ;] execute
On 2024-03-07 21:58, minforth wrote:
Ruvim wrote:
Let's take the definition:
: foo [: 123 . ;] execute ;
There is no a convincing reason why the following lines should not be
observationally equivalent:
foo
[: 123 . ;] execute
Then this should also be equivalent?
: BLA ." 1 " ;
BLA
" 1 "
Yes, `BLA` and `." 1 "`.
Yes,
BLA
and
." 1 "
Anyhow IMO quotations are crippled as long as they can't access upvalues.
E.g.
: TTT { a } [: a . ;] dup execute 2 to a execute ;
1 TTT -> 1 2
If they could access local variables of a containing definition — they should be called "closures", not "quotations".
On 2024-03-07 16:29, Ruvim wrote:
The accepted proposal for quotations [1] specifies only compilation
semantics for the words "[:" and ";]".
The expected interpretation semantics for "[: ... ;]" are that this
construct behaves like ":noname ... ;" (at least for the resulting stack
effect), but the system should correctly work regardless whether the
current definition exists (i.e., a definition that is being compiled).
It means, if a definition is being compiled, its compilation shall be
correctly suspended by "[:", and resumed after ";]" under the hood.
Bellow are the test cases for the standardized compilation semantics,
and for the expected interpretation semantics.
Interestingly, some Forth systems fail the t12 and t13 tests for the
standardized compilation semantics.
[...]
===== start of "quotation.test.fth"
\ Test cases for quotations "[: ... ;]"
\ Testing the compilation semantics
\ t11
t{ :noname [: 123 ;] ; execute execute -> 123 }t
: lit, postpone literal ;
: ([:) postpone [: ;
: (;]) postpone ;] ;
\ t12
t{ :noname [ ([:) (;]) ] ; 0<> -> -1 }t > \ t13
t{ :noname 1 [ ([:) 2 lit, (;]) ] 3 ; execute swap execute -> 1 3 2 }t
t12 roughly tests that the compilation semantics for the words "[:" and
";]" can be correctly performed programmatically.
This test fails in Gforth, VfxForth, minForth.
The problem is that the system enters compilation state after executing >"([:)". But it shall not. This action cannot be a part of compilation >semantics at all (it's not possible to correctly specify this action,
and it is not actually specified for the "[:" compilation semantics).
Ruvim <ruvim.pinka@gmail.com> writes:
On 2024-03-07 16:29, Ruvim wrote:
The accepted proposal for quotations [1] specifies only compilation
semantics for the words "[:" and ";]".
The expected interpretation semantics for "[: ... ;]" are that this
construct behaves like ":noname ... ;" (at least for the resulting stack >>> effect), but the system should correctly work regardless whether the
current definition exists (i.e., a definition that is being compiled).
It means, if a definition is being compiled, its compilation shall be
correctly suspended by "[:", and resumed after ";]" under the hood.
Bellow are the test cases for the standardized compilation semantics,
and for the expected interpretation semantics.
Interestingly, some Forth systems fail the t12 and t13 tests for the
standardized compilation semantics.
[...]
===== start of "quotation.test.fth"
\ Test cases for quotations "[: ... ;]"
\ Testing the compilation semantics
\ t11
t{ :noname [: 123 ;] ; execute execute -> 123 }t
: lit, postpone literal ;
: ([:) postpone [: ;
: (;]) postpone ;] ;
\ t12
t{ :noname [ ([:) (;]) ] ; 0<> -> -1 }t > \ t13
t{ :noname 1 [ ([:) 2 lit, (;]) ] 3 ; execute swap execute -> 1 3 2 }t
t12 roughly tests that the compilation semantics for the words "[:" and >>";]" can be correctly performed programmatically.
This test fails in Gforth, VfxForth, minForth.
Is there any Forth system where this test succeeds? I.e., is this
supposed failure actually common practice?
The problem is that the system enters compilation state after executing >>"([:)". But it shall not. This action cannot be a part of compilation >>semantics at all (it's not possible to correctly specify this action,
and it is not actually specified for the "[:" compilation semantics).
Let's see. <http://www.forth200x.org/documents/forth19-1.pdf> says:
|Suspends compiling to the current definition, starts a new nested >|definition with execution token xt, and compilation continues with
|this nested definition.
The CfV on which it is based <http://www.forth200x.org/quotations.txt>
uses the same wording.
One could argue that "compilation continues" allows switching to
compilation state, so it's not clear that this test should succeed.
But anyway, it is better to improve the wording to make this switch
explicit.
And probably similarly for ";]". We would have to check whether all
systems switch to compilation state after the compilation semantics of
;], or whether some restore the state before "[:".
- anton
In minForth, "[:" leaves some data on the return stack, and ";]"
consumes this data from the return stack (contrary to the
specification). So, it fails in the following test case:
t{ : [t14] ( -- ) 123 >r ([:) r> lit, (;]) ; immediate -> }t
t{ :noname [t14] ; execute execute -> 123 }t
Although I find it obvious and not worth the hassle, the specification
should be amended so that "a program shall not use the return stack to
pass data between outer and inner functions, i.e. from an enclosing word
to its inner quotation(s) of any nesting depth, or from a quotation to
its outer enclosing word regardless of its nesting depth".
This is the most expected way because analogously
123 >r :noname r> lit, ;
is also not guaranteed to work in ISO Forth.
minforth@gmx.net (minforth) writes:
Although I find it obvious and not worth the hassle, the specification >>should be amended so that "a program shall not use the return stack to
pass data between outer and inner functions, i.e. from an enclosing word
to its inner quotation(s) of any nesting depth, or from a quotation to
its outer enclosing word regardless of its nesting depth".
If you think so, make a proposal. In the rest of the standard, the compilation semantics of control-flow words communicate through the control-flow stack, which usually is the data stack. I see no reason
to make an exception for [: ... ;].
This is the most expected way because analogously
123 >r :noname r> lit, ;
is also not guaranteed to work in ISO Forth.
However,
: foo 123 >r :noname r> postpone literal postpone ; ;
foo execute . \ prints 123
is guaranteed to work in Forth-94 (ISO Forth) and Forth-2012.
Anton Ertl wrote:
minforth@gmx.net (minforth) writes:
Although I find it obvious and not worth the hassle, the specification >>>should be amended so that "a program shall not use the return stack to >>>pass data between outer and inner functions, i.e. from an enclosing word >>>to its inner quotation(s) of any nesting depth, or from a quotation to >>>its outer enclosing word regardless of its nesting depth".
If you think so, make a proposal. In the rest of the standard, the
compilation semantics of control-flow words communicate through the
control-flow stack, which usually is the data stack. I see no reason
to make an exception for [: ... ;].
Some systems might use the return stack for local frames. But well, then >follows probably 'implementation-defined' or 'ambiguity' ...
However,
: foo 123 >r :noname r> postpone literal postpone ; ;
foo execute . \ prints 123
is guaranteed to work in Forth-94 (ISO Forth) and Forth-2012.
There is no control flow here.
Look at
<https://forth-standard.org/standard/usage#subsection.3.1.5>: There
are system-compilation types on the control-flow stack (which may be
the data stack), and system-execution types on the return stack.
minforth@gmx.net (minforth) writes:
Although I find it obvious and not worth the hassle, the specification >>should be amended so that "a program shall not use the return stack to
pass data between outer and inner functions, i.e. from an enclosing word
to its inner quotation(s) of any nesting depth, or from a quotation to
its outer enclosing word regardless of its nesting depth".
If you think so, make a proposal. In the rest of the standard, the >compilation semantics of control-flow words communicate through the >control-flow stack, which usually is the data stack. I see no reason
to make an exception for [: ... ;].
This is the most expected way because analogously
123 >r :noname r> lit, ;
is also not guaranteed to work in ISO Forth.
However,
: foo 123 >r :noname r> postpone literal postpone ; ;
foo execute . \ prints 123
is guaranteed to work in Forth-94 (ISO Forth) and Forth-2012.
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
BTW many CATCH/THROW implementations use the return stack in a similar way, >> i.e. they don't use an exception stack.
CATCH ( i*x xt -- j*x 0 | i*x n )
The state of the return stack after performing CATCH is the same as
before performing.
The accepted proposal for quotations [1] specifies only compilation...
semantics for the words "[:" and ";]".
The expected interpretation semantics for "[: ... ;]" are that this
construct behaves like ":noname ... ;"
Interestingly, some Forth systems fail the t12 and t13 tests for the standardized compilation semantics.
\ t11
t{ :noname [: 123 ;] ; execute execute -> 123 }t
: lit, postpone literal ;
: ([:) postpone [: ;
: (;]) postpone ;] ;
\ t12
t{ :noname [ ([:) (;]) ] ; 0<-> -1 }t
\ t13
t{ :noname 1 [ ([:) 2 lit, (;]) ] 3 ; execute swap execute -> 1 3 2 }t
\ Testing the interpretation semantics
\ (the expected behavior)
\ t21
t{ depth [: ;] depth 1- = ?dup nip -> 0 }t
\ t22
t{ [: 123 ;] execute -> 123 }t
\ t23
t{ [: 1 [: 2 ;] 3 ;] execute swap execute -> 1 3 2 }t
\ Testing the interpretation semantics
\ doing compilation of another definition
\ (the expected behavior)
\ t31
t{ [: [ depth [: ;] depth 1- = ?dup nip ] literal ;] execute -> 0 }t
\ t32
t{ [: 1 [ [: 2 ;] ] literal 3 ;] execute swap execute -> 1 3 2 }t
===== end of "quotation.test.fth"
[1] http://www.forth200x.org/quotations-v4.txt
--
Ruvim
In article <2024Mar10.193700@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
minforth@gmx.net (minforth) writes:
However,
: foo 123 >r :noname r> postpone literal postpone ; ;
foo execute . \ prints 123
is guaranteed to work in Forth-94 (ISO Forth) and Forth-2012.
I thought that
"
123 >r : noname r> postpone literal postpone ;
noname . \ prints 123
"
is not guaranteed to work in Forth-94 (ISO Forth).
Why is this different?
minforth@gmx.net (minforth) writes:
Although I find it obvious and not worth the hassle, the specification >>should be amended so that "a program shall not use the return stack to
pass data between outer and inner functions, i.e. from an enclosing word
to its inner quotation(s) of any nesting depth, or from a quotation to
its outer enclosing word regardless of its nesting depth".
If you think so, make a proposal. In the rest of the standard, the >compilation semantics of control-flow words communicate through the >control-flow stack, which usually is the data stack. I see no reason
to make an exception for [: ... ;].
This is the most expected way because analogously
123 >r :noname r> lit, ;
is also not guaranteed to work in ISO Forth.
However,
: foo 123 >r :noname r> postpone literal postpone ; ;
foo execute . \ prints 123
is guaranteed to work in Forth-94 (ISO Forth) and Forth-2012.
- anton
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 41:40:43 |
Calls: | 6,708 |
Calls today: | 1 |
Files: | 12,243 |
Messages: | 5,353,855 |