On Sunday, 4 July 2021 at 08:43:11 UTC, Alexandru Ermicioi wrote:
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.

```d
immutable(Foo) example(ref Foo input)
{
    Foo mutableCopy = input;
    mutableCopy.mutate();
    return immutable(Foo)(mutableCopy); // call copy ctor
}
```

I guess if your object is very expensive to copy you might want to use `cast(immutable)` here, but IMO the real solution is to refactor your code so that the call to `.mutate()` is not necessary.

For example, let's say that what `mutate` does is change the member variable `bar`. You could rewrite the above as:

```d
immutable(Foo) example(ref Foo input)
{
    auto copy = immutable(Foo)(
        // update this field
        computeNewValue(input.bar),
        // copy the rest
        input.baz,
        input.quux,
        /* ... */
    );
    return copy;
}
```

Reply via email to