What to do when you want to add attributes to your class functions?

H. S. Teoh hsteoh at qfbox.info
Sat Sep 17 00:26:03 UTC 2022


On Fri, Sep 16, 2022 at 10:55:46PM +0000, Dukc via Digitalmars-d wrote:
> On Friday, 16 September 2022 at 09:25:58 UTC, RazvanN wrote:
> > Let's say you have a library class that exposes some methods. At the
> > beginning you did not focus on the safety, nogcness etc. of your
> > methods, you just wanted to have something working. You publish your
> > class, people start using it and now you are in a phase where you
> > would like your methods to be callable from attributed contexts. So
> > you go on and make your code safe, nothrow, nogc, pure. However, now
> > you are faced with a large breaking change because suddenly you
> > force your users to respect these attributes.

One way this could have worked is, if your library code was written with
the most restrictive attributes that would still allow it to work.  Then
code with less restrictives attributes would still be able to call your
code (because your code would be covariant with the more relaxed
attributes). E.g., if your code was written to be `pure` as much as
possible, then it could be called from both pure and impure code.
However, if you didn't pay attention to purity in the first place and a
lot of your code is impure, then pure code would not be able to call
your code.  Similarly, if your code was written to be @safe (whether or
not you initially write the attribute explictly), then @system code
could still call it.

However, this approach may run into problems when user code may inherit
from your class.  Derived class overrides cannot expand the
permissiveness of the overridden base class method's attributes; it can
only restrict it -- e.g., if a base class method is pure, then it would
be invalid to allow a derived class to override it with an impure
method, because then pure code could invoke the impure code via the base
class's pure interface. This implies that base class methods must be
maximally permissive, in order to accomodate derived classes. But that
means that it would not be callable from a more restrictive context.
Thus this defeats our goal.

//

The other way to do it is to use templates and allow the compiler to do
attribute inference. You'd write your code under maximal restrictions,
and use unittests to enforce purity, nothrow, etc., but leave the actual
template code unattributed to allow the compiler to infer attributes. So
if the user code is pure, your code would not introduce impurity and it
would work. If the user code is impure, the compiler just infers impure
and it would still work.

However, template methods cannot be overridden by inheritance, so we
haven't really solved the inheritance issue either.


[...]
> > Now, the entire point of this post is to ask what should we do in the
> > case of: https://github.com/dlang/dmd/pull/14432.
[...]

Good question. :/  Given that in this case the base class API is already
fixed, seems the best you could do is to add attributed overloads in the
derived class. Which is an ugly solution. :-(


T

-- 
I think Debian's doing something wrong, `apt-get install pesticide', doesn't seem to remove the bugs on my system! -- Mike Dresser


More information about the Digitalmars-d mailing list