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