Result type spreading

I think people can agree that writing

const result: u16 = @as(u16, @intFromFloat(float1)) + 
                    @as(u16, @intFromFloat(float2));

is painful. I am thinking that Zig can have a result type spreading mechanism. Right now, if an expression is assigned to a variable, it gets the type based on RLS, which is essentially

const result: u16 = @as(u16, @intFromFloat(float1));

We can imagine that

const result: u16 = @intFromFloat(float1) + @intFromFloat(float2);

is the same as

const result: u16 = @as(u16, @intFromFloat(float1) + @intFromFloat(float2));

This obviously doesn’t work, but what if Zig automatically spreads the @as calls when it sees +, -, * or / binary operators, so the above code becomes

const result: u16 = @as(u16, @intFromFloat(float1)) + 
                    @as(u16, @intFromFloat(float2));
4 Likes

I think this makes sense.
Especially considering that there are already similar proposals to propagate result types to more operators:
Proposal: restrict `++` to allow it to interact with RLS · Issue #24908 · ziglang/zig

However, similar proposals have already been rejected in terms of arithmetic symbols.

RLS for bitwise not operator `~` · Issue #25497 · ziglang/zig

The reason for the rejection is equally convincing: This change is breaking, and under the same expression, the semantics commonly used in the past and the semantics accepted for this modification will be completely opposite. Especially when the vast majority of languages adopt forward type derivation rather than backward derivation of result types.

However, I believe the more fundamental reason why previous related similar proposals were rejected lies in the lack of sufficient consistency. I absolutely cannot accept the adoption of result type derivations for only a few of these symbols, but if all mathematical symbols were to adopt result type derivations, I would readily accept it.

But the problem with breaking remains huge.

its worth mentioning allow integer types to be any range · Issue #3806 · ziglang/zig · GitHub

The semantics of them is that operations will result in a type with an increased/reduced range, depending on the operation. This removes trivial casting. The benefit of that is you can just write equations without caring for the size until the end.

Ofc wrapping and saturating operators will still exist, with the addition of asserting operators, which keep the current behaviour.