On Saturday, 3 July 2021 at 20:09:56 UTC, tsbockman wrote:
On Saturday, 3 July 2021 at 16:06:33 UTC, Alexandru Ermicioi
wrote:
3. An edge case. Ex: You need to mutate some data and then
assume it is immutable in a constructor.
Can you give a valid example where that is necessary? The main
examples that I can think of either can be `@safe` with the
right API, or are motivated by a desire to avoid the GC and/or
druntime, thus falling under (1).
Can't remember any specific code now, but suppose you have a
mutable object as input to a function or constructor. You need to
return or assign an immutable copy of that struct and you can do
that with right copy constructor on that object, but before that
you need to do a couple of mutations on that object. In this use
case you can't avoid cast(immutable) easily. Note: it is desired
to not mutate the original object.
The summary is this: the construction of immutable instances can
be done just through initialization statement. You can't mutate
the instance and then assign/assume it as an immutable.
4. Functionality that doesn't account for @safe/immutable or
any other features when it can in standard library.
True, although it's just another example of my point (2). The
standard library and druntime are dependencies, too...
Right, didn't take it that way.
The one exception here is when the array is already typed
`inout` before it is passed to the constructor. But, that's an
example of (2) since this logic applies transitively throughout
the call stack: if you need to call `dup` anywhere, don't erase
the constness with `inout`.
Yeah this is a working workaround, for this specific use case. I
still would prefer inout version, even if I need to do some
unsafe casts due to clear intentions it gives the user, and
better errors.
Anyway this is just a proof of your 2nd point.