equivariant functions
Benji Smith
dlanguage at benjismith.net
Tue Oct 14 19:51:46 PDT 2008
Andrei Alexandrescu wrote:
> Benji Smith wrote:
>> I really don't see what all the fuss is about with the equivariance
>> stuff, except that it introduces a lot of confusing rules to fix the
>> holes in the (already complex and confusing) const system.
>
> Please stop perpetuating misunderstanding and apprehension about the
> const system through statements strong on opinion and vague on detail.
> If you're willing to mention holes, complexity, and confusion about the
> const system, please explain where the holes are, where the complexities
> lie, and what aspects you are confused about. Suggestions for fixing
> said issues would also be welcome.
Fair enough. Here are the reasons I describe the const system as "complex":
* Comparable code without const qualifiers contains quantatitively fewer
semantic constructs than code that uses those qualifiers. Smaller
function prototypes are easier to read and comprehend:
char[] join(char[] str2, char[] str2) { ... }
const(char)[] join(const(char)[] str1, const(char)[] str1) { ... }
* Nestable const type constructors require me to keep a more detailed
mental model of the type system. Am I using a "const(char)[]" or a
"const(char[])"?
* Remembering the difference between "const" and "invariant" requires
more mental energy than using a system (D1) where such distinctions
don't exist.
* The idea that "const" is a supertype of "mutable" and "invariant" is
utterly bizarre to me, since it violates the "is a" rule of type
hierarchies. I understand that, for the sake of overloading, both
"mutable" and "invariant" can be implicitly cast to "const", but the
other implications of that relationship are beyond my grasp at the moment.
* The transitivity of const qualifiers requires me to consider not just
the object I'm passing around, but the references to other objects
contained within the const-qualified object.
* Both "const" and "invariant" can apply to value-type objects. But
"const" doesn't make any sense in that context, so in my mind I have to
use the "invariant" concept instead whenever applying the concept to a
primitive value.
* The equivariance proposal, at least in some of its forms, requires me
to imagine the existence of implicit typedefs at the function-call site,
and to know that the declared type in my method signature might not be
the actual type of the arguments received by the function.
The "holes" I described in the const system are the symptoms being
addressed by the equivariance proposal. Without equivariance, the const
system sometimes requires verbatim duplication of code within function
bodies whose only difference is their signature. Without the const
system, the equivariance proposal wouldn't be necessary.
And the reason I describe the const system as "confusing"?
Because it confuses me.
I understand some of the allure of having a robust, provably correct
const system. Automatic memoization would be cool. Automatic parallel
execution would be nice. And, in theory, it'd be nice to avoid errors
that occur when a piece of code modifies a piece of data that it shouldn't.
But in my experience (using languages that lack any sort of const
system, except for enum-style declarations), it just doesn't matter
much. When I need memoization or parallel execution, I write the code
explicitly. And when I need an immutable object, I design its interface
to make external mutation impossible (see also: java.lang.String).
It's indisputable that the D2 const system is measurably more complex
than the D1 const system.
For me, the cost of that complexity significantly outweighs the benefit.
--benji
More information about the Digitalmars-d
mailing list