First Draft: Static Single Assignment
Walter Bright
newshound2 at digitalmars.com
Wed Dec 3 08:31:42 UTC 2025
On 11/27/2025 11:41 AM, Jonathan M Davis wrote:
> Okay, what's the real motivation here?
The motivation is to find a way to express "single assignment".
Single assignment has gained traction in programming circles, as for long
functions it can be hard to track if the value gets reassigned in the function
or not. By tagging with `final` the compiler can enforce it to you.
I've been refactoring my code to use single assignment, as it makes the code
more readable.
> If it's to prevent assignment, then
> IMHO, that's what the DIP needs to say. It should not talk about preventing
> "modification" or "mutation." If that's what you want, then just use const.
> So, assignment needs to be called out as illegal rather than talking about
> mutation or modification being illegal.
const is different, as it is transitive.
> Of course, that also leaves the question of "op assignment"
They're disallowed for `final` declarations.
> final int i = 42;
> i += 10;
>
> should be legal,
I'm sorry, but the point is to make that illegal.
> should be illegal. And if the desire is to prevent operations like += as
> well, then const or immutable should be used. If that's not the case, then
> we're going to have a very weird situation with user-defined types.
Once a user defined type is constructed, if is final, then it cannot be modified.
> Of course, the other issue here is that because final is a storage class and
> not a type qualifier, things are going to degrade to const pretty quickly
> with pointers and references. For instance,
>
> final int i = 42;
> auto ptr = &i;
>
> is going to have to make ptr const(int)* or const(int*)
or simply disallowed. I hadn't thought of that case, though there are surely
more cases I didn't think of!
> But to handle that cleanly in more complex cases, you'd really need final to
> be a proper type qualifier, which would mean something like
>
> final int i = 42;
> final(int)* ptr = &i;
>
> since without that, it all degrades to const, significantly reducing the
> utility of final in such code, but making final a type qualifier also opens
> a very large can of worms which we probably don't want to open.
I don't want to open that either, hence making it a storage class. I understand
the desire to make it part of the type system, but I want to make it not part of
the type system.
> Of course, personally, I don't think that this feature adds enough value to
> be worth adding at all, but it does feel very much like something being
> welded onto the language to solve a corner case that doesn't work with const
> rather than having a more holistic solution.
I intend `final` to be optional and have it not have a complicated set of rules
for it. It is intended to be lightweight.
> In any case, I really think that the DIP needs to be very clear about how
> it's about assignment and _not_ about mutation, and the situation with the
> compound assignment operators (which get overloaded with opOpAssign) needs
> to be made very clear for both user-defined types and primitive types,
> whereas the issue really isn't discussed at all with what's currently in the
> DIP.
Compound assignment operators would not be allowed on final declarations. And it
must be about preventing mutation, or it is worthless.
More information about the dip.development
mailing list