D has become unbearable and it needs to stop
Adam D Ruppe
destructionator at gmail.com
Thu Jun 15 12:35:37 UTC 2023
On Thursday, 15 June 2023 at 07:07:18 UTC, Walter Bright wrote:
> Restore the old getAttributes behavior, and create a new
> getAttributes2 with the new behavior.
>
> Will that work for you?
This is often even worse than just changing the original, so such
things need to be evaluated on a case-by-case basis.
For the case of getAttributes, there's nothing actually wrong
with the original behavior! The proposed getAttributes2 would be
exactly identical to getAttributes, except that it gives a
deprecation message on certain (currently ambigously defined, but
could easily become defined) uses. There's no benefit to this and
it would just add to long-term confusion as new people wonder
what the differences are between the two.
(Something similar happened with getVirtualMethods and
getVirtualFunctions. One was simply defined incorrectly and
instead of fixing it, the other was introduced with a subtly
different definition. That one is more justifiable than
getAttributes2 would be, since it actually *was* defined, and
*maybe* that subtle difference matters, and it is hard for the
compiler to statically detect. But now the current result is you
have a function that is wrong and a function that is right
sitting side by side with only a careful reading of the docs
revealing which is which.)
What I would suggest for getAttributes is either:
Option 1: Define its status quo behavior on the spec. If passed
an overloaded function symbol, it will return the attributes of
the lexically first function in the set. There's nothing actually
wrong with that if people know what to expect and how to work
with it! Put in the docs: Tip: you can use getOverloads to loop
over all the overloads in the set. Optionally, change
getOverloads so it also works on non-functions, so you can always
loop over names and overloads (Even if a set of one item in the
case of non-overloadable entities) without a separate branch.
OR
Option 2 (my preference): Sit down and define what, exactly, an
overload set is in the language and make it into its own
conceptual model with associated definitions in the reflection
system. I don't have a specific proposal for D right now, but in
my little script.d language, I made overload sets actually be an
object with opCall defined. This is, of course, different since
script.d is a dynamic language so many things, including overload
resolution, happen at runtime. Indeed, this design was less about
conceptual purity than about laziness in implementation - I
already had objects and opCall working, so defining an object
that internally had an array of functions and dispatched it was
fairly easy.
But a side effect is the rest of the language can still work with
it. I can loop over the overloads by... just literally looping
over the overload set member in the object. You can detect it is
an overload set by comparing object types. Other properties can
be attached to it, etc.
That exact implementation is not right for D, but perhaps
something similar could work. We could define all kinds of things
in both the docs and in the language, iron out some edge cases,
and make reflection easier to use.
You might even do both of these options, #1 in the short term,
and #2 as part of a complete overhaul of the reflection system.
Our random collection of of traits has served D well so far, but
a second draft can learn a lot from its real world lessons and
then both would exist side by side as a compatibility bridge.
More information about the Digitalmars-d
mailing list