D's greatest mistakes

Steven Schveighoffer schveiguy at yahoo.com
Tue Nov 30 13:24:11 PST 2010


On Tue, 30 Nov 2010 15:47:22 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 11/30/10 12:38 PM, Steven Schveighoffer wrote:

>> No, that's not what I'm saying. Creating a language-based tail-const
>> solution *unifies* all references, including any smart references you
>> can create. I can say tail-const anything and it always means the same
>> thing. It's another tool to allow creating of smart references. Without
>> this, we have to special case tail-const in all smart reference types.
>> If anything Rebindable is a special case smart reference, it only
>> addresses class tail-const. The language solution addresses general
>> tail-const. E.g. how does Rebindable address tail-const ranges?
>>
>> I see it 100% opposite from what you are saying, a library solution
>> looks to me like "look! we don't have to change the language to add
>> language features, all you need is this template that adds 10k of bloat
>> to your exe! And why do you need to pass them as parameters, just create
>> a new local variable? And why do you need it to work with *all*
>> reference types, there's other syntax for that!" All for the sake of not
>> changing the language, which I think is the more direct and complete
>> solution. I don't really understand the resistance.
>
> Understanding the "resistance" is very simple. Right now a lot of  
> current readers cheerily ignore this thread. Also a lot of potential  
> users couldn't care any less. Once the feature will be in the language,  
> it will affect them all.

It affects them all as much as Rebindable affects them all.  Either way,  
it's something new they have to learn, whether it's a language feature or  
a library feature.  This argument makes no sense.

Another way to look at it -- whichever solution is used is really going to  
affect only library writers, not library users.  Whether the user writes:

@tail const(C);

or

Rebindable!(const(C))

or something else is really irrelevant to them, what's relevant is what  
hoops do I as a library writer have to jump through to get this damned  
thing to work seamlessly.

> When we defined the const system, we had some goals: guaranteed  
> immutability, simple unification of functional and procedural, economy  
> of means. We were well aware of the tail const issue, and we made the  
> executive decision that we will punt on it on account of it being  
> relatively rare in practice, and partially addressable with Rebindable.  
> As of this time I don't know whether that is true or not.

To determine whether tail-const is useful or not, let's examine all uses  
of tail-const and tail-immutable in phobos that *don't* involve classes.   
I.e. const(T)[] arrays, and const(T)* pointers.

Rebindable does not work, that much I do know.  Pointing at lack of use of  
Rebindable is not proof of anything except that it's a half baked feature.

I also don't know that tail-const references will be mainstream useful or  
just useful on a small scale.  I know that it directly affects the project  
I wrote.  As of now, dcollections containers are const-unfriendly because  
to implement const would require massive duplication of all ranges and  
functions that accept ranges, plus implicit casting just doesn't work  
between two different template instantiations that vary only on const.

Whether the language is modified so this can work, or the language  
incorporates tail-const directly, it's a problem that needs to be solved  
IMO.  Which is the right answer, I don't know, but the builtin explanation  
seems to me to allow more efficient code, and less boilerplate required.

> Now say we define @tail const or whatever. That serves a case of  
> questionable frequency with an in-language solution that affects anyone  
> learning the language. This is a huge deal. I don't understand your not  
> understanding.

Why is the frequency questionable?  Isn't every use of string an example  
of tail-immutable?  Isn't string used everywhere?

> So please let's look into what the limitations of library-based  
> solutions are. We shouldn't be triumphantly proclaiming that Rebindable  
> is insufficient or inadequate. We should be looking into ways of making  
> it and other library solutions work, and understand that relying on an  
> in-language solution would be defeat, not victory. Every problem that  
> makes Rebindable not work also invalidates other useful designs.  
> Conversely, relying on a narrow language change that builds Rebindable  
> into the language definition would address the occasional tail-const  
> situation but will miss the train on many other, larger, issues.

I'm not at all proclaiming victory because Rebindable sucks.  I think  
something that allows Rebindable to properly work would be great for  
something less commonly used than tail-x, but I'd rather have the code be  
cleaner for a feature that's used everywhere.  We could do away with array  
syntax, or operators, and just go with function calls and elemAt(size_t),  
but I swear and punch things every time I have to use C#'s arrays,  
lamenting for how D's syntax works.  Syntax is important too.

If you can make Rebindable!(T) become tail const for every type of T  
(including a range), and have it work flawlessly when casting to/from  
const(T), then I accept that as a valid solution.  If Rebindable just  
solves the tail-const class case, and I have to do something *like* what  
Rebindable does whenever I want to allow tail-const on any type, then I  
think the problem is not yet solved.

> Same discussion goes about non-nullable. We don't need the compiler to  
> understand non-nullable types, we need to imbue the compiler with the  
> ability to enforce arbitrary user-defined state invariants, non-null  
> being one of them.

Non-nullable is a different animal.  Non-null types do not really exist  
everywhere in D.  Tail-const/shared/immutable types exist everywhere in  
D.  There is no lack of consistency in D for non-nullable types.

>>>> To go with your analogy, we own the bank (compiler), we can print our
>>>> own money...
>>>
>>> And we all know where that takes.
>>
>> Better compiler? Better smart references? Yep, I agree :)
>
> I meant bankruptcy.

How does this translate to the software analogy?  What does bankruptcy for  
dmd mean?

Note that we can print our own money and not have to pay it back, it's  
software :)

-Steve


More information about the Digitalmars-d mailing list