[Second Review] SE-0410: Atomics

I think @ksluder has an important point with all this. Though I understand the pragmatist arguments for mutable atomic lets, they seem to be teetering on the edge of a slippery slope into 'madness', for the lay-programmer.

And as Kyle mentioned, the justifications for them have thus far been presented in very esoteric language terms, which I struggle to translate (or conceive being translated) to lay-programmer explanations.

I'm what you might call a definite Enthusiast of Swift, with a notably deeper knowledge of the language than average, but even I have to read and re-read a lot of these debate threads very slowly and carefully to grok the rationales and language behaviours.

The problem - that was unfortunately set up long before this proposal - is twofold:

  1. The Swift language defines var vs let as variables vs constants, right from the very start. It's literally the first concept introduced in the official Language Guide.

    Of course, as we all know, it then goes on to violate that deeply, once reference types are introduced and constants become suddenly not constant. Worse, you can't even tell from the use-site whether a let is actually a constant or not (even if you're just considering apparent behaviour, let-alone literal behaviour).

    But, just because you're in a hole already isn't a great reason to dig a deeper one.

  2. Swift doesn't distinguish between constant references and constant values. C's const int* const etc. So it's fundamentally incapable of expressing this basic nuance of mutability control.

I've never liked the behaviour of let with reference types, and it seems very obviously a hacky workaround to problem #2 (above). It confused me right at the outset - and still to this day - that I can declare a constant and then modify its value. It makes it practically impossible to use the language to control mutability - you have to do things Objective-C style with NSString vs NSMutableString patterns - which were more elegant in Objective-C because of the consistency with which they were used and how it interplayed with other aspects of the language, none of which is the case with Swift, but have always had big pitfalls even in Objective-C (e.g. the need to aggressively -copy all object inputs all the time, which almost nobody ever did, so nominally immutable values mutate underneath you all the time).

Emphasising that point, any time I read the words "you just need to make a wrapper" I die a little inside. Swift code is so full of boilerplate and ceremonial wrappers already, the last thing it needs is even more of them.

(also, Swift makes it unduly difficult to 'just' create wrapper types, because of things like the inability to forward protocol conformances, so while it always looks passable in trivial examples in these Forum threads, when you get real world, non-trivial types, making wrappers becomes an ordeal)

I don't know what this proposal should do, as it's just a victim of the existing language here. But there was mention of a potential way to make var work for atomics, through compiler improvements, and that does seem promising. If we can avoid let atomics, that will at least make this one part of the language / stdlib less confusing.

Or, put another way: an Atomic<T> for a value type T should itself behave like a value type, at least in this respect. I think that's part of what Kyle's alluding to with the atomic keyword hypothetical (which, to be honest, I find enticing - 'atomicness' is to me an attribute of variable, not a type).

17 Likes