equivariant functions

Benji Smith dlanguage at benjismith.net
Wed Oct 15 16:56:17 PDT 2008


Hey, Andrei!

First of all, just let me say how much I appreciate your detailed 
responses. I hope you don't ever take my feedback as a personal 
criticism or as being harshly negative. The only reason I've continued 
to engage is these kinds of debates for the last five years or so is 
because D interests me very much, and I'd like to see it meet its 
fullest potential. I know you have the same end-goals in mind, though we 
sometimes disagree about the most effective route from point A to point B.

Andrei Alexandrescu wrote:
> I see where you're coming from. If your opinion is that the const system 
> does not bring enough benefits to justify its learning, you are of 
> course entitled to it. But talking about complexity implies that there 
> would be simpler ways to achieve its charter that we missed, and talking 
> about holes that we made mistakes of principle that go beyond bugs in 
> the compiler or incompleteness of implementation.

Yeah, I see where you're coming from too. I think you guys have done an 
admirable job thinking through the corner cases and figuring out ways to 
solve many of the sticky design issues that have arisen.

On the other hand, there was a const proposal...maybe six months or a 
year ago...where all function parameters would be considered immutable 
by default, unless annotated as mutable.

I thought that idea had a lot of merit. My first impression was that 
it'd provide more reliable guarantees, since it would be impossible to 
accidentally create a mutable param by forgetting to declare its 
constness. It also seemed like it would have resulted in more compact 
method signatures (since const arguments are generally more common than 
mutable arguments), and less overall risk of aliasing.

For me, one of the main perks of the other proposal was less "const" 
litter all over the code, and yet with stronger const safety.

Also, a function promising not to modify its arguments seems more like 
an attribute of the function, not of the arguments themselves.

But I digress...

>> * 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[])"?
> 
> You don't need to keep a more detailed mental model of the type system - 
> whatever that is :o). On the contrary, const allows you to free your 
> mind of many details about the data flow in your application. If you 
> make a mistake regarding const(char)[] vs. const(char[]), the compiler 
> will tell you about it, not one night of debugging.

The "mental model" is my cute little informal way of referring to the 
body of knowledge necessary to operate some contraption (like a can 
opener or a compiler).

In order to make the gizmo do what I want it to do, I have to form a 
(perhaps simplified) mental picture of the cause-and-effect chain that 
connects the inputs with the outputs.

Driving a car with a manual transmission requires a more detailed mental 
model than driving an automatic. Maybe the manual transmission offers 
other advantages, but ease-of-use is not one of them.

>> * Remembering the difference between "const" and "invariant" requires 
>> more mental energy than using a system (D1) where such distinctions 
>> don't exist.
> 
> I think this reflects a misunderstanding of what constness is supposed 
> to do for you. It's exactly the contrary. Invariant reduces the amount 
> of mental energy you need to expend. I think you owe it to yourself to 
> use D2. You will see that using invariant strings is a huge improvement 
> and it alone is worth introducing constness. Literally all bugs caused 
> by undue aliasing disappear if you use string. You will see that the net 
> result is that your programs are easier to write and understand, not 
> harder.

I actually plan on giving D2 a spin as soon as a compatible version of 
Tango is available.

And I actually totally agree with you about invariant strings. The 
languages I use most often (Java, C#, Python) all have immutable 
strings, without the languages having a const system like D. In those 
languages, immutability is achieved by convention.

It's a tradeoff, sure.

Especially when implementing a new class, you have to think carefully 
about when to make defensive copies in getters and setters. And external 
consumers of your classes, who might not know where the defensive copies 
occur, might create their own defensive copies before calling one of 
your API methods. In that respect, a const system is alluring because it 
eliminates the need for those kinds of considerations.

But the const system just smells bad to me. I've tried to enumerate my 
reasons, and maybe switching to D2 will change my mind. But right now, 
I'm calling it as I see it. You asked for feedback, and you got it!!

I'll make an analogy.

I also find the concept of range-bound numeric types very appealing. 
It'd be nice to declare that a function takes an argument whose value is 
a "double greater than zero but less than or equal to one". A lot of my 
statistical code would benefit from that kind of type declaration, and 
I'd be able to get rid of a few lines of argument-validity-checking code 
from the preamble of every function implementation.

While we're at it, I can also think of examples where I might like to 
say that a function accepts a "feature vector whose magnitude is exactly 
equal to 1.0".

Input validation is one of those nasty cross-cutting concerns, and it'd 
be nice to have a general-purpose, language-level solution to the problem.

It doesn't take too much imagination to sketch out a design for 
extending the type system to allow for those kinds of value constraints. 
With such a type calculus in place, it would probably be possible to 
implement a general purpose solver that would enable a whole host of 
interesting optimizations.

If I'm not mistaken, that's the basic idea of many functional 
languages... That by moving computation into the type system, the 
algebraic rules governing those types can be solved by applying 
well-known type transformations, often in parallel.

Nevertheless, I think range-bound types would be a mistake to implement 
in D. I can't completely articulate why I feel that way, but part of it 
has to do with the increasing complexity of function prototype 
declarations. And, it's also partly because validation can already be 
accomplished in an "in" contract.

To me, the const system has the same basic characteristics: it's a major 
language feature, with lots of corner cases, to solve a problem that I 
either don't have or have already found a reasonable (if not ideal) 
solution.

>> * 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.
> 
> You may want to reframe this as an opportunity to improve your 
> understanding of subtyping. I recommend a classic paper by Cardelli and 
> Wegner "On understanding Types, Data Abstraction, and Polymorphism" 
> (http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf). It's a 
> classic. Reading through section 1.5 does not require much background 
> and is very rewarding.

I just read section 1.5 and don't find anything outlandish there.

And I've added the paper to my reading list. Language design is fun, and 
I'm always looking for new good source material :)

>> * 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.
> 
> This is backwards, too. If const didn't exist or weren't transitive, 
> you'd be required to keep in mind for mutation and aliasing bugs not 
> just the object you're passing around, but the references to other objects.

Again, I'd like to reaffirm my agreement that immutable objects are 
valuable. No disagreement from me there!

I'm just used to an ecosystem where immutability is by convention, and 
the language-level immutability in D strikes me as somewhat heavy-handed.

>> * 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.
> 
> Not at all. On this group many people have high competency and willing 
> to discuss the most minute implementation details of a language feature, 
> and my understanding is that you also engage in such discussions. On 
> occasion, therefore, there will be discussion on exactly how sausages 
> are being made. Do not confuse those discussions with things that 
> complicate the experience of eating sausages.

Yep! I love to engage in these kinds of discussions!

And I hope you take this in the spirit of informed disagreement. I read 
about 90% of the messages in this NG, paying particular attention to the 
language-design discussions. I've taken the stuff I learned in this NG 
from geniuses like you and Walter, and used it in real-life projects, 
implementing a domain-specific language and compiler for one of my 
former employers.

I'm sure you get tired of people throwing stones at your design 
concepts, especially without a detailed explanation. But I think many of 
us also get tired of being told "if you really understood, you'd agree".

I may not fully understand all the details, but I understand enough to 
know that I'm not a fan.

And I disagree about the "sausage-making". I've never successfully used 
a language feature, in any programming language, where I didn't 
understand the underlying mechanics of the implementation. Anyone 
writing code who doesn't know how it works under the hood is just a 
copy-paste programmer.

Anyhow, I'll leave it at that.

Since this community presumably exists to support a collaborative 
environment for advancing the D language (and does a remarkably good job 
of it in the vast majority of cases), I just wanted to put my vote in 
the ballot-box.

:-)

--benji



More information about the Digitalmars-d mailing list