,---------------. | Contributions | `---------------´ ,------------------------------------------ | 2022-06-20 17:34:22 poggingfish wrote: | referenceImplementation - | see: https://forth-standard.org/standard/core/TwoTimes#contribution-239 `------------------------------------------ ``` : 2* 2 * ; ``` ,------------------------------------------ | 2022-06-20 17:40:33 poggingfish wrote: | referenceImplementation - | see: https://forth-standard.org/standard/core/RFetch#contribution-240 `------------------------------------------ ``` : R@ R> dup >R ; ``` ,---------. | Replies | `---------´ ,------------------------------------------ | 2022-06-14 08:08:56 AntonErtl replies: | requestClarification - Same execution token | see: https://forth-standard.org/standard/usage#reply-821 `------------------------------------------ My take is that `foo` and `bar` are equivalent as far as the execution token is concerned. Once you have the execution token, you cannot determine their name or immediacy with standard means. There are systems that allow access to the name and/or immediacy with non-standard means, and these systems will choose to produce different xts for `foo` and `bar`. Actually I don't know any system that would produce the same xt for `foo` and `bar`. The only standard case where I expect that a system may produce the same xt is for a synonym. But this statement is older than synonyms, so what is it about? A program might want to check for a certain condition by comparing with an xt, and on a system with code deduplication that produces the same xt for definitions that result in the same code, this might not work as intended. Given the common practice of not having code deduplication, do we want to restrict the statement to synonyms, in order to let programs use the technique outlined above? ,------------------------------------------ | 2022-06-15 10:24:11 ruv replies: | requestClarification - Same execution token | see: https://forth-standard.org/standard/usage#reply-822 `------------------------------------------ > My take is that `foo` and `bar` are equivalent as far as the execution token is concerned. So you want to say that the execution semantics of `foo` and the execution semantics of `bar` are equivalent (the same), and then these execution semantics may be identified by the same execution token. Actually, it's obvious from the terms definitions: an execution token identifies execution semantics, so the same execution token identifies the same execution semantics. Not so obvious that the same execution semantics may be identified by the **different** execution tokens. Concerning 3.1.3.5 — due to its wording ("to *have* execution token"), it says not about equivalent execution semantics, but about equivalent Forth words (named Forth definitions), and their associated execution tokens (when these tokens can be retrieved by a standard program). And in my example the **words** `foo` and `bar` (that are named Forth definitions) are not equivalent, and then **their definitions** are not equivalent, and then 3.1.3.5 is not applicable to this case. If we want 3.1.3.5 be applicable to this case, we should reword it, I think. For example, we can replace 3.1.3.5 by the following list (1): - Different Forth definitions may have the same execution token if these definitions define the same execution semantics. - Different execution tokens may identify the same execution semantics. - When an execution token **can** be obtained by a program before the corresponding execution semantics are defined, this token shall be unique among all the available execution tokens at the moment. > But this statement is older than synonyms, so what is it about? Probably some system-specific alternatives were already known, e.g. `alias` or alike. Also, for example, the same execution token can be easy implemented for constants having the same value, for plain synonyms like `: foo2 foo1 ;`, for noops like `: foo3 ;` and other simple cases when the generated code is identical. > A program might want to check for a certain condition by comparing with an xt, and on a system with code deduplication that produces the same xt for definitions that result in the same code, this might not work as intended. Yes, I'm also bothered on this regard. > Given the common practice of not having code deduplication, do we want to restrict the statement to synonyms, in order to let programs use the technique outlined above? In the latter item in the list (1) I suggest the certain cases when the standard requires xt to be unique. At the moment, it covers only noname-definitions. But I'm going to propose a word `germ ( -- xt|0 )` that returns xt of the current definition (a definition being compiled, including a quotation). After that all colon-like definitions (colon, noname, quotation) will have a unique xt among each other, and it meets the common practice. ----- > Once you have the execution token, you cannot determine their name or immediacy with standard means. Yes, since neither name, nor immediacy are properties of an execution token. But you can find some words this execution token is associated with. ,------------------------------------------ | 2022-06-15 10:55:26 StephenPelc replies: | requestClarification - Same execution token | see: https://forth-standard.org/standard/usage#reply-823 `------------------------------------------ Saying that words are equivalent if their execution semantics are identical is a ghastly mistake. For example `IF` is equivalent to `THEN`. Children of `CREATE`, `VALUE` and `VARIABLE` are distinct definitions. At the very least, think of the disambiguation issues. ,------------------------------------------ | 2022-06-15 19:03:56 ruv replies: | requestClarification - Same execution token | see: https://forth-standard.org/standard/usage#reply-824 `------------------------------------------ > Saying that words are equivalent if their execution semantics are identical is a ghastly mistake. Of course, it's obvious. And it would be too easy disprovable by a counterexample. So I don't think Anton meant that. Usually, in such contexts "equivalence" means operational equivalence (observational equivalence). Formally, two Forth definitions are equivalent if (and only if) no such a program exists (a standard program) that always halts when one definition is used and never halts when another definition is used. In practice, it's usually enough to demonstrate different behavior in some test case. ,------------------------------------------ | 2022-06-21 09:53:12 ruv replies: | referenceImplementation - | see: https://forth-standard.org/standard/core/RFetch#reply-825 `------------------------------------------ > ``` > : R@ R> dup >R ; > ``` This variant is incorrect. Implementation dependent variants: ``` : r@ ( -- x ) ( R: x addr -- x addr ) r> r> tuck >r >r ; : r@ ( -- x ) ( R: x addr -- x addr ) 2r> over >r >r ; ``` These variants are not standard compliant since they conflicts with [3.2.3.3 Return stack](https://forth-standard.org/standard/usage#subsubsection.3.2.3.3) and they will not work on some systems (nevertheless, it's acceptable for reference implementations). A portable variant (standard compliant): ``` : r@ postpone r> postpone dup postpone >r ; immediate ``` ,------------------------------------------ | 2022-06-21 13:13:41 ruv replies: | referenceImplementation - | see: https://forth-standard.org/standard/core/RFetch#reply-826 `------------------------------------------ >> ``` >> : R@ R> dup >R ; >> ``` > This variant is incorrect. Well, actually this variant can be used in some systems (i.e., it's implementation dependent too), namely for systems in which *nest-sys* always takes 0 cells (see *initiation semantics* for [colon](https://forth-standard.org/standard/core/Colon) and [noname](https://forth-standard.org/standard/core/ColonNONAME)) . While the implementation dependent variants provided by me are for systems in which *nest-sys* always takes 1 cell (majority of Forth systems without an optimizing compiler). But all variants in which `r@` is defined as an ordinary word don't support some expected equivalences. Namely, it means that the compilation semantics for such `r@` can be performed by applying `execute` to its *xt* as `['] r@ compile,`, and then the following test case will fail: ``` : execute >r r@ execute r> drop ; : compile, postpone literal postpone execute ; : [execute] execute ; immediate bl word r@ ' find ] [execute] [ nip -1 = [if] t{ :noname 123 >r [ ' r@ compile, ] r> drop ; execute -> 123 }t [else] .( The test-case is not applicable to this Forth system ) cr [then] ``` So I would consider such implementations as incorrect. As a real life example, Gforth 0.7.9_20220428 fails this testcase. ,------------------------------------------ | 2022-06-21 14:02:12 ruv replies: | referenceImplementation - | see: https://forth-standard.org/standard/core/RFetch#reply-827 `------------------------------------------ > the compilation semantics for such `r@` can be performed
> by applying `execute` to its *xt* It's a typo. It should be read as: "by applying `compile,` to its *xt*"