What to do when you want to add attributes to your class functions?
Dukc
ajieskola at gmail.com
Fri Sep 16 22:55:46 UTC 2022
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.
As with anything, it's about finding the most practical solution
overall for everyone involved. Unless you're publishing low-level
system code (not very likely with classes), the usual
cost-benefit radio from best to worst is IMO `@safe`, `pure`,
`nothrow`, `@nogc`.
Considering a library done from stratch, I'd say that most
abstract functions should have first two of those attributes but
not the last two. But if you need to consider backwards
compatibility, one option to consider is going only with `@safe`.
Less breakage than with `@safe pure`, and breaking code can
cowboy it with `@trusted // GREENWASHED: Not reviewed for safety`
to each of those. Or better yet, actually review those functions
for safety.
> This seems like a severe limitation to me.
It is a limitation, that's for sure. But I think it may be less
severe than you think. Missing `nothrow` and `@nogc` attributes
are far from the worst problems in a typical application code.
Many would say that there they aren't even worth the visual
clutter they are.
And if you don't mark your code `pure` and `@safe` well before
you publish it for everyone to use in non-alpha state, it
suggests that you don't consider even those attributes quite
essential. It's arguable if that's a good attitude, but it's
quite popular judging by this forum.
>
> It just seems simpler to never use attributes at all (with
> classes).
That's close to a good advice with regards to `nothrow` and
especially `@nogc`. I think that even if your abstract function
should in principle be implemented without throwing or garbage
collecting, it's often a good idea to omit those attributes just
to make life easier for the child function implementor. Maybe
even omit `pure`. But at least use `@safe` unless you have strong
specific reasons not to (like heavy issues with backwards
compatibility - I'd probably defer adding `@safe` to next major
version of the library). Making an abstract function `@system`
puts much more burden to anyone who uses the class and cares
about safety, than it saves burden from those implementing the
children functions.
>
> 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.
Disclaimer: I had only a surface look on what `Condition` seems
to do. It's pretty likely I'm not on map on how it works and how
it's supposed to be used.
I would not add `@nogc` to the interface of this function. A
reasonable implementation might use the heap to do some
bookkeeping and might want to allocate on `notify`. An ideal
implementation would not do so, but abstract classes should
generally be easy to implement even from not-so-perfect code.
It can be questioned why the same class acts both as an abstract
class for other implementations, and an implementation in itself.
If there was a separate `final class` that implemented
`Condition`, it's members could be `@nogc`. The downside would be
that the class instance would be a bit bigger since D object grow
with number of interfaces/classes they inherit - maybe that's why.
More information about the Digitalmars-d
mailing list