No argument that the conv_* matrix is cruft, and collapsing conversions
between numeric types is a real, appealing win. So I'm with you on the
goal.
My worry is that "all numbers are one fungible double" isn't how the
systems HAL has to talk to work. IEC 61131-3, CANopen/EtherCAT object
dictionaries, modbus, OPC UA all keep integer, real and bit-string as
distinct types with explicit conversion between them. None of them has a
universal number type. So an internally type-erased HAL doesn't remove
the type problem, it pushes it to every external boundary, and
converting a typed 64-bit value to a double at that boundary is lossy.
As HAL becomes more of a bridge to those buses, that cost grows rather
than shrinks. The configgen in linuxcnc-ethercat already maps EtherCAT
int64 straight to s64; that 1:1 mapping is what we'd be giving up.
On the counter point specifically: the clean wrap is exactly a property
the standards keep by keeping integer types. hal_extend_counter()
reconstructs an integer count with modular arithmetic, no lost counts. A
double can't do that; past 2^53 it degrades and the low bits are gone,
and a getter/setter warning can flag it but can't recover them. So if a
count becomes a double pin, we lose the clean wrap that integers give us
for free.
On 64-bit masks being hypothetical: they already exist. The EtherCAT
distributed clock is a 64-bit value and the Beckhoff EL5032 puts a
64-bit count on the PDO, both in linuxcnc-ethercat now. The hi/lo split
is what we do today, and it's the thing to avoid, not the fallback: two
pins tear (low from one cycle, high from the next, off by 2^32) and
tools can't show the real value.
And that's what bitslice/bitmerge want underneath: a word/bit type, with
bool as its 1-bit member. Emitting 32 floats of 0/1 instead drops the
bool type, and your cosmic-ray note actually argues the same way, a
defined bit is more robust than a float near 1.
So I'd keep the split the standards already draw, integer, real, and
bit-string as distinct, and aim the simplification at the conversions
that are genuinely redundant, rather than erasing types we then have to
reconstruct at every fieldbus boundary.
On 6/8/2026 6:31 AM, andy pugh wrote:
On Sun, 7 Jun 2026 at 15:59, Luca Toniolo<[email protected]> wrote:
Fair, the magnitude case is rare and I won't push it. But the behaviour at the
limit differs. An integer counter wraps at a known point and we already
reconstruct it: hal_extend_counter() extends limited-width counters to 64 bits
with the usual modular trick, so the count just keeps going, no discontinuity,
no lost counts. A float past 53 bits doesn't wrap, it degrades silently, x + 1
== x and the count eventually sticks, with no boundary to detect and nothing to
recover. So where it matters, the integer keeps counting correctly and the
float quietly loses count.
A getter/setter interface could warn/error at this point.
I _think_ that the underlying driver code would ask for a specific
type back from the interface, it would be absolutely _only_ the pins
that were all fungible doubles.
The motivation is to make HAL easier for users. Doing this would make
the conv_*_* components unnecessary. You can connect anything to
anything. (and you are on your own if that's a silly thing :-) )
Either way, magnitude isn't the only reason for integer pins. It's also the
values that aren't counts: registers, status and fault words, masks. Those
don't round or wrap, the bit pattern just has to survive, which a double can't
do. sserial already carries them as hal_u32_t pins for exactly that reason.
It does, but currently we have no 64-bit masks or registers.
Worst-case if those appear the driver component would have to provide
high-byte and low-byte HAL pins.
One honest question: what would bitslice and bitmerge operate on without an
integer type? Their job is word-to-bits and bits-to-word.
These would probably remain as 32-bit components. The pin-names would
be the same, they could be connected freely to any other HAL pin,
internally they would be interpreted as 32-bit ints and treated
accordingly.
(And bitslice would output 32 floats with values of 0 or 1) [1]
[1] In Sinclair basic, on the Z80, "True" was 0xFF and "False" was
0x00. That seems like a better scheme, more resilient to single-bit
flips by cosmic rays.
_______________________________________________
Emc-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/emc-developers