Why are you using `std.traits.fullyQualifiedName`?
Adam D Ruppe
destructionator at gmail.com
Sat Jan 21 12:43:30 UTC 2023
On Saturday, 21 January 2023 at 05:21:15 UTC, Richard (Rikki)
Andrew Cattermole wrote:
> 1) Uniquely identifying a type (registration of types for
> things like serializing, passing to hash function ext.).
the compiler uses .mangleof for this purpose and druntime uses
typeid(). FQN is just an even bigger, but no more unique,
presentation of mangleof.
> 2) Pretty printing for debugging. Here is some output that I
> generated yesterday:
>
> - sidero.base.datetime.time.timezone.TimeZone(
This case is trivial to get out of existing language capabilities
(including very, very quickly by slicing into mangleof).
Why is the Phobos implementation so complicated then? Well, some
of it is unnecessary complexity, but much of it has to do with
the various different kind of template arguments (and most the
rest of it is due to function overloads). And these can again be
extracted from mangleof, I said this in the github thread, but
many times these actually harm readability.
For debugging, there's a good chance you'd actually rather have a
partially qualified name tied together with a source location.
Which is more likely to help debugging:
random.d:1081 std.random.Mt19937
or
std.random.MersenneTwisterEngine!(uint, 32, 624, 397, 31,
0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18,
1_812_433_253)
?
(Phobos and the trait in the PR picks the latter.)
Now, I'll grant this is a bit unfair because the compiler never
exposes alias names anymore (though it used to, and I consider
this a regression, it broke some of my code that used to reflect
on those :( ). But even:
random.d:1081 std.random.MersenneTwisterEngine
without the arguments listed is better for debugging. And this is
a simple one. In the PR thread, I mentioned
`structFromTable!(import("db.sql"), "MyTable");` That
representation in source isn't too bad. The definition point is
pretty readable. The fullyQualifiedName is dozens of kilobytes
dumped to the screen. Is this useful?
A trait to get the aliased name would be far more useful! At
least the global aliased name; a local one like `template a(alias
A) {}` always returning A not that interesting, but if the alias
name is in an outer scope, that's actually valuable information.
Now, I will grant there are some places where template args help:
struct Thing {
Nullable!int a;
Nullable!string b;
}
If that just printed `std.typecons.Nullable` as the type, you are
missing something. How do you know which one is worth printing
and which one isn't? It probably depends... which means it is
better done by library code.
At the same time, there is something the compiler can potentially
do here, and again, I mentioned this in the PR thread: it could
use its knowledge of scopes to disambiguate.
It could print this as Nullable or Nullable!int unless there's
another Nullable in scope, in which case it prints the module
name - std.typecons.Nullable - to clear it up. The compiler has
the knowledge and the existing code to do this for error
messages. So exposing it might be of some value.
But .... we need to identify the concrete intended use case.
Error messages and debugging aren't even exactly the same and
they're very different than code generation.
Just.... since we have the library capabilities to do all this
with as much or as little customization as desired, does the
language need to bloat it up offering a bunch of options?
But regardless, the one option it proposes to offer right now is
not ideal for any use case.
More information about the Digitalmars-d
mailing list