,---------------.
| Contributions |
`---------------´
,------------------------------------------
| 2024-06-11 15:56:58 ruv wrote:
| requestClarification - Data type of a parameters in `c!`
| see: https://forth-standard.org/standard/core/CStore#contribution-342
`------------------------------------------
Is the following fragment standard compliant?
```
-1 pad c!
```
The glossary entry for `c!` says:
> _( char c-addr -- )_
> When character size is smaller than cell size, only the number of low-order bits corresponding to character size are transferred.
It seems, the text description implies a stack diagram _( x c-addr -- )_ or _( char|x c-addr -- )_.
,---------.
| Replies |
`---------´
,------------------------------------------
| 2024-06-02 05:19:13 BerndPaysan replies:
| requestClarification - Usage of the `n|u` data type
| see: https://forth-standard.org/standard/core/Plus#reply-1225
`------------------------------------------
See A.3.2.1 how deeply the assumptions of two's complement are rooted into Forth. Therefore, the operations `+` and `-` work interchangeable for unsigned and signed, and even mixed. If your system is not two's complement, unsigned is restricted to +n.
IIRC, not using two's complement is no longer an option.
,------------------------------------------
| 2024-06-03 15:04:14 bfox9900 replies:
| referenceImplementation - Possible Reference Implementation
| see: https://forth-standard.org/standard/string/SEARCH#reply-1226
`------------------------------------------
I should read the specification more closely.
This correction gives the correct output if search fails to find the string.
Reduced some stack juggling with the dreaded PICK.
```
: SEARCH ( caddr1 u1 caddr2 u2 -- caddr3 u3 flag)
BEGIN
DUP
WHILE
2OVER 3 PICK OVER COMPARE
WHILE
1 /STRING
REPEAT
2NIP TRUE EXIT
THEN
2DROP FALSE ;
```
```
,------------------------------------------
| 2024-06-04 15:40:50 ruv replies:
| comment - Data object notion usage
| see: https://forth-standard.org/standard/usage#reply-1227
`------------------------------------------
As I see it, to solve the mentioned problem with the notion and definition of "data type", a more detailed formalization is required.
The main premise: every data object is _formally_ associated with a set of data types.
Thus, we can talk about "typed data objects" (an abstraction), data objects that are associated with data types:
A _typed data object_ is an ordered pair of a data object and a set of data types.
Consequently, every data type determines an _abstract_ set of _typed data objects_. And it's possible to determine where a _typed data object_ is a member of a data type (namely, a member of the set that is determined by that data type).
So where are "values"? A value for a typed data object is determined by data types. And since a typed data object may belong to several data types (for example, to _n_ and to _flag_), it may have a set of different values. But one data type determines only one value for one data object (that is allowed to be associated with this data type).
> A data type identifies the set of permissible values for a data object.
So, a variant that seems more correct:
**A data type identifies a set of data objects and a value for each data object from that set.**
If somebody interested, see [my attempt](https://gist.github.com/ruv/76ac54cf3bb520f65fd31de02db0cf17) of a more detailed formalization, a feedback is welcome.
,------------------------------------------
| 2024-06-04 16:01:55 AntonErtl replies:
| requestClarification - Usage of the `n|u` data type
| see: https://forth-standard.org/standard/core/Plus#reply-1228
`------------------------------------------
For the moment, let's take the Forth-94/2012 position that the result on integer overflow (i.e. where a mathematical integer addition produces a result outside the target range) is implementation-defined. Let's say I want to avoid that; even then I can construct cases for various combinations of n and u; to make things more concrete, let's assume that the range of n is -32768..32767 and for u it is 0..65535:
```
1 1 + \ gives 2; +n1 +n2 -- +n (where +n is both u and n)
33000 -1 + \ gives 32999; u1 n2 -- u
33000 -1000 + \ gives 32000; u1 n2 -- +n
1 -2 + \ gives -1; +n1 n2 -- n
-1 -1 + \ gives -2; n1 n2 -- n
20000 20000 + \ gives 40000; +n1 +n2 -- u
```
For the stack diagrams with +n, you could produce either one with n or with u instead of the +n, which means that in the first case you can have all 8 combinations.
These are all standard Forth programs where the mathematical integer result is in the target range, so no, the diagram is not limited to be equivalent to `( n1 n2 -- n3 | u1 u2 -- u3 )`. My take is that n|u means a range of -32768..65535 for the example ranges above, just as +n (i.e., n&u) means 0..32767.
In 2015 the committee accepted [2s-Complement Wrap-Around Integers](http://www.forth200x.org/twos-complement.html), which defines what happens in those cases where the result does not fit in the target range; with that it is up to the programmer in all cases how to interpret the arguments and the results of `+`; e.g., the `-1 -1 +` case for the ranges given above can also be interpreted as:
```
65535 65535 + \ gives 65534; u1 u2 -- u
```
,------------------------------------------
| 2024-06-05 16:25:57 ruv replies:
| comment - Data object notion usage
| see: https://forth-standard.org/standard/usage#reply-1229
`------------------------------------------
>> Moving a data object shall not affect its type. (2)
> Granted, I also find (2) confusing. In my case, it's because it implies that objects somehow "know" their type.
I think, a purpose of this statement is to guarantee a property that can be illustrated by the following examples.
Let's consider the word `swap ( x1 x2 -- x3 x4 )`. It moves (in some sense) the data objects, but this shall not affect their data types (NB: a data object may be a member of several data types, not only the data type _x_). That is, not only the data objects in the stack parameters _x3_ and _x2_ are equal, but also their sets of data types are equal. I.e., they are equal as _typed data objects_. Ditto for _x4_ and _x1_.
Ditto for the sequential operations `! ( x1 a-addr -- )` and `@ ( a-addr -- x2 )` for the same address: the typed data objects in the stack parameters _x2_ and _x1_ are equal.
Ditto for the result of the `move` operation, etc (when you write data objects into one location, then copy them into another location, and then read from another location).
,------------------------------------------
| 2024-06-05 16:49:53 ruv replies:
| requestClarification - Usage of the `n|u` data type
| see: https://forth-standard.org/standard/core/Plus#reply-1230
`------------------------------------------
One idea, why the operations `+` and `-` should be defined when one argument in _u_, and the other argument in _n_ is that these operations on any integer arguments should be equal to a series of operations on `0` and `1`.
Any number in _u_ that is outside of the _n_ range can be represented as the sum of several numbers in _n_.
For example, `max-uint` is the sum of numbers (`max-int`, `max-int`, `1`), (supposing two's complement).
Thus, an operation on numbers in _n_ and _u_ should be equivalent to several operations in _n_ only, resulting in _n_ (taking into account the overflow rule) (1).
Any number in _n_ that is outside of the _u_ range can be represented as the subtraction of two numbers in _u_.
For example, `min-int` is the subtraction of unsigned( `max-int` + `1`) from `0` (assuming two's complement).
Thus, an operation on numbers in _n_ and _u_ should be equivalent to several operations in _u_ only, resulting in _u_ (taking into account the overflow rule) (2).
I don't sure whether (1) and (2) both are always true for one's complement and sign-magnitude representations, but they are true for two's complement representation.
It means, that the result of `+` and `-` , when one argument in _n_, and the other in _u_, always belongs to **both** _u_ and _n_ data types, and in some cases it also belongs to the _+n_ data type.
Also, if one (and not the other) of the arguments is in _addr_, the result (in the general case) is in _u_ and in _addr_ , but not in _n_.
-----
It seems, (1) and (2) are also true for `* ( n1|u1 n2|u2 -- n3|u3 ) `.
,------------------------------------------
| 2024-06-06 17:05:04 AntonErtl replies:
| proposal - Fix stack comments for N>R and NR>
| see: https://forth-standard.org/proposals/fix-stack-comments-for-n-r-and-nr-#reply-1231
`------------------------------------------
## Author:
* Anton Ertl
* Leon Wagner
## Change Log
* 2024-06-06 replaced some `n` with `+n`; formatting changes (AE)
* 2023-09-14 Revision after discussion (AE)
* 2023-09-13 Initial proposal
## Problem:
The stack comments for N>R and NR> don't make it clear that _+n_ items are moved between the data and return stacks.
## Solution:
The stack comments should more clearly indicate that _+n_ data stack items are moved to or from the return stack.
## Proposal:
In the definition of [`N>R`](https://forth-standard.org/standard/tools/NtoR), replace
> `( i * n +n -- ) ( R: -- j * x +n )`
with
> `( x_n ... x_1 +n -- ) ( R: -- j*x +n )`
In the definition of [`NR>`](https://forth-standard.org/standard/tools/NRfrom), replace
> `( -- i * x +n ) ( R: j * x +n -- )`
with
> `( -- x_n ... x_1 +n ) ( R: j*x +n -- )`
## Discussion
On the return stack, `j*x +n` because the data may be in a separate buffer and only the address and `+n` on the return stack. `+n` on the return stack because the original specified that, and changing that would be a substantial change.
On the data stack `x_n ... x_1 +n` because that is the way we usually specify a numbered number of cells (even for `+n=0`). See, e.g., [`get-order`](https://forth-standard.org/standard/search/GET-ORDER).