Command–query separation principle [re: @mustuse as a function attribute]

Mike Parker aldacron at gmail.com
Wed Oct 19 08:15:32 UTC 2022


On Wednesday, 19 October 2022 at 07:41:33 UTC, mw wrote:
>
> Covariance and contravariance is a big topic by itself.
> But ..., what does it have anything to do here with @mustuse as 
> a function attribute?
>
> @mustuse here only enforces there must be a receiver of the 
> function call result, and do not throw away the returned result.
>
> I'd really like to see some examples what's this concern is 
> about.
>

Following are the examples Walter provided in his email 
discussions with Paul:

Covariance Ex. 1:

```d
class C {
   T h();
}
class D : C {
   override @mustuse T h();
}
```

Ex. 2
```d
class C {
   @mustuse T h();
}
class D : C {
   override T h();
}
```

Contravariance Ex. 1:
```d
class C {
    void t(T function() @mustuse *);
}
class D {
    override void t(T function() *);
}
```

Ex 2:
```d
class C {
    void t(T function() *);
}
class D {
    override void t(T function() @mustuse *);
}
```

The rules for what happens in each case need to be clearly 
defined. Walter proposed the following:

====
To establish the rule, just resolve this simple case:

```d
T f();
@mustuse T g();
```

Can g be implicitly coerced into the type of f? No.
Can f be implicitly coerced into the type of g? Yes.

I.e. @mustuse can be added in an implicit type conversion, but it 
cannot be
subtracted. That's all we need to know, everything else follows 
inevitably.
====

In which case, both Examples 1 would fail, and both Examples 2 
would pass.

There was more to their discussion beyond this, though, and I'm 
not the person to summarize it.

So again, if anyone wants to take a stab at fleshing it out, 
please let me know. I can ask Paul and Walter to provide their 
thoughts to help get started.


More information about the Digitalmars-d mailing list