auto: useful, annoying or bad practice?
Nick Sabalausky (Abscissa)
SeeWebsiteToContactMe at semitwist.com
Fri May 4 04:12:09 UTC 2018
On 05/02/2018 10:05 AM, H. S. Teoh wrote:
>
> I've been using structural typing / design by introspection to good
> success in my latest project, actually.
I don't doubt that. Similar to global namespace, if the structural
typing is only used heavily by one or two components of a project (ie,
libs, etc), then it's not too difficult to avoid problems. The real
danger and problems come when a project uses several components that all
make heavy use of either a global namespace (which D luckily doesn't
really have) or structural typing.
>> Structral typing isn't "If it walks like a duck and quacks like a
>> duck...". Structural typing is "If it walks and it talks, then it
>> must be a duck, because ducks walk and have their own form of talk, so
>> clearly anything that walks and talks must be a duck."
>
> How else would you do DoI, though? With Concepts? The advantage of
> using structural typing over concepts for DoI is that you would need an
> exponential number of concepts to catch up with a linear number of
> optional fields in a structural typing model. Sure, structural typing
> has its warts, but it's at least more scalable in this respect.
With a slight variation on structural typing that's augmented with
mandatory opt-in. I'll explain:
The problem with structural typing is that it's unable to distinguish
between intended matches and accidental, unintended matches. This is
because it doesn't REQUIRE types/functions/etc to clearly state, "Yes, I
*intend* to be implementing interface XYZ". Or perhaps more accurately:
"Yes, I *intend* for this to satisfy isXYZ!T". (Where "isXYZ" might be
something like "isInputRange" or "isInfiniteRange", or both, etc.)
Note the all-caps "REQUIRE" in the paragraph above. That is to say, it's
not enough for the developer of struct Foo to toss in...
static assert(isXYZ!Foo);
...because the problem doesn't lie with the "intended matches". The
problem lies with the "unintended matches". And that static assert does
nothing to help isXYZ figure out that some other type, Bar, from some
other package, is NOT deliberately designed to satisfy isXYZ even if it
just happens to *look* like it satisfies it purely by chance.
As an aside: Think you're not likely to hit false positives with
structural typing? Well, in all honestly, unless you're really sloppy,
you're not likely hit name collisions in the global namespace
either...UNTIL you reach the point where projects are composed of many
third-party packages, and most third party packages start using the
global namespace in their own way. Then it becomes a distinct possibility.
The same dynamic applies here because, like global namespaces,
structural typing (by default) has no mechanism for scope-limiting or
compartmentalization, and (intentionally) operates on unqualified names.
We address the global namespace's lack of scope-limiting and
compartmentalization through...well, namespaces. The namespaces may be
implied by classes (old-school Java), by compilation units (D), or
specified manually (C++). But how do we address structural typing's lack
of scope-limiting and compartmentalization? Currently, we don't. And
that's the problem.
So back you your question: How else would you do DoI?
Answer: By making isXYZ!T reject all T which DO NOT satisfy a
deliberate, cannot-be-an-accident, condition of isXYZ's choosing.
Thus, type T *cannot* satisfy isXYZ without T's developer saying "Yes, I
hereby certify it is my deliberate intention that T satisfies isXYZ and
that, if it does satisfy, it is by my own intention and not by
coincidental happenstance."
The exact details of this condition aren't terribly important, but I
like Neia's suggestion of utilizing UDAs for this purpose. An old idea I
had before UDAs existed was to require a dummy member enum named
something like _satisfies_module_foo_bar_isXYZ, which of course would be
abstracted away by something more convenient...a mixin or such (but
nobody seemed remotely interested). But I like the UDA idea better.
More information about the Digitalmars-d
mailing list