March 16, 2014

On 16.03.2014 15:24, Manu wrote:
> On 16 March 2014 21:28, Rainer Schuetze <r.sagitario@gmx.de
> <mailto:r.sagitario@gmx.de>> wrote:
>
>
>     alias export extern(Windows) void function() fnWINAPI;
>
>     @functionAttributesOf!fnWINAPI HANDLE GetCurrentProcess();
>
>
> I frequently find myself needing something like this. What's wrong with
> aliasing attributes directly?
> DGC/LDC offer their own internal attributes, but you can't make use of
> them and remain portable without an ability to do something like the
> #define hack in C.

Unfortunately, it doesn't fit very well with the grammar to allow something like

alias @property const final nothrow @safe pure propertyGet;

(or some special syntax) and then parse

propertyGet UserType fun();

because it's ambiguous whithout semantic knowlegde of the identifiers. It becomes unambiguous with UDA syntax, though:

@propertyGet UserType fun();

I suspect propertyGet would have to describe some new "entity" that needs to be able to be passed around, aliased, used in CTFE, etc.
March 16, 2014
Daniel Murphy:

> If anyone wants to try this out on their code, the patch I used was to add this:
>
> if (ad && !ad->isInterfaceDeclaration() && isVirtual() && !isFinal() &&
>    !isOverride() && !(storage_class & STCvirtual) && !(ad->storage_class & STCfinal))
> {
>    warning(loc, "virtual required");
> }
>
> Around line 623 in func.c (exact line doesn't matter, just stick it in with the rest of the checks)
>
> I also had to disable the "static member functions cannot be virtual" error.

In the meantime has someone else measured experimentally the amount of breakage a "final by default" causes in significant D programs?

Bye,
bearophile
March 16, 2014
On 13/03/14 16:57, Andrei Alexandrescu wrote:
> At a level it's clear it's not a matter of right or wrong but instead a judgment
> call, right? Successful languages go with either default.

Sorry for the delay in responding here.

Yes, it is a judgement call, and what's more, I think that probably just about all of us here recognize that you and Walter need to make such judgement calls sometimes, to mediate between the different requirements of different users.  In this case, what really bothers me is less that I disagree with the judgement call (that happens), more that it was a decision reached without any kind of community engagement before finalizing it.

This isn't meant as some kind of misguided call for democracy or voting or "respecting the community's wishes" -- the point is simply that every decision made without prior discussion and debate carries a social cost in terms of people's ability to make reliable plans for future development.

This is particularly true when the decision (like this) is to reverse what most people seem to have understood was an accepted and agreed-on development goal.

> The breakage was given as an example. We would have decided the same without
> that happening.

Understood.  I hope it's clear why this was not apparent from the original announcement.

> More than sure a well-executed deprecation process helps although it's not
> perfect. We're not encumbered by exhausting confidentiality requirements etc.

Thanks for clarifying that.  I'm sorry if my question about this seemed excessively paranoid, but it really wasn't clear from the original announcement how much of the motivation for the decision arose out of client pressure.  I felt it was better to ask rather than to be uncertain.

Regarding deprecation processes: I do take your point that no matter how well planned, and no matter how obvious the deprecation path may seem, any managed change has the potential to cause unexpected breakage _simply because things are being changed_.

On the other hand, one thing that's apparent is that while substantial parts of the language are now stable and settled, there _are_ still going to have to be breaking changes in future -- both to fix outright bugs, and in areas where judgement calls over the value of the change go the other way.  So, I think there needs to be some better communication of the principles by which that threshold is determined.  (Obviously people will still argue over whether that threshold has been reached or not, but if the general framework for deciding yes or no is well understood then it should defuse 90% of the arguments.)

> There's some underlying assumption here that if we "really" understood the
> arguments we'd be convinced. Speaking for myself, I can say I understand the
> arguments very well. I don't know how to acknowledge them better than I've
> already done.

Actually, rather the opposite -- I know you understand the arguments very well, and therefore I have much higher expectations in terms of how detailed an explanation I think you should be prepared to offer to justify your decisions ;-)

In this case part of the problem is that we got the decision first and then the more detailed responses have come in the ensuing discussion.  In that context I think it's pretty important to respond to questions about this or that bit of evidence by seeing them as attempts to understand your train of thought, rather than seeing them as assumptions that you don't understand something.

That said, I think it's worth noting that in this discussion we have had multiple examples of genuinely different understandings -- not just different priorities -- about how certain language features may be used or how it's desirable to use them.  So it's natural that people question whether all the relevant evidence was really considered.

> Thanks for being candid about this. I have difficulty, however, picturing how to
> do a decision point better. At some point a decision will be made. It's a
> judgment call, that in some reasonable people's opinion, is wrong, and in some
> other reasonable people's opinion, is right. For such, we're well past
> arguments' time - no amount of arguing would convince. I don't see how to give
> better warning about essentially a Boolean decision point that precludes
> pursuing the converse design path.

I think that it's a mistake to see discussion as only being about pitching arguments or changing people's minds -- discussion is also necessary and useful to set the stage for a decision, to build understanding about why a decision is necessary and what are the factors that are informing it.

One of the problems with this particular issue is that probably as far as most people are concerned, a discussion was had, people pitched arguments one way and the other, some positions became entrenched, other people changed their minds, and finally, a decision was made -- by you and Walter -- in favour of final by default.  And even though some people disagreed with that, everyone could see the process by which that decision was reached, and everyone felt that their opinions had been taken into account.  And that was that -- a decision.

So, now, you and Walter have changed your minds -- which is fine in and of itself.  The question is, is it right for you to simply overturn the old decision, or is it more appropriate for you to take the time to build a new consensus around the facts that have changed since the last one?

My own take on that is that the maintainer's trump card is an essential but precious resource, and that generally speaking its use should be reserved for those situations where there is an absolutely intractable dispute between different points of view that cannot be resolved other than by the maintainer's decision.  And I don't think that this is such a situation.

Anyway, for what it's worth, here's how I think I would have gone about this (bearing in mind that hindsight is 20/20:-).  I would not have jumped straight to the final-by-default decision, but would have laid out the problem that needs solving -- that we need to raise the bar much higher in terms of avoiding unexpected breaking change -- and then I'd have raised the related issue: "However, we also need to take a long hard look at the _planned_ breaking changes we have in mind, and give serious consideration to which of them are really necessary, and which are merely desirable."  And I'd have asked for opinions, thoughts and so forth on this.

And _that_ would have been the context in which it'd have been the right moment to raise the issue of final-by-default, and probably to justify its exclusion on the grounds that while it is very desirable, it is not actually fixing an unworkable situation -- merely a problematic one.

I think that while in that context there would certainly still have been many concerned responses questioning the decision, but there wouldn't have been the feeling that it was a decision being imposed out of the blue for unclear reasons.
March 16, 2014
On 13/03/14 16:22, Andrei Alexandrescu wrote:
> On 3/13/14, 2:15 AM, John Colvin wrote:
>> In light of this and as a nod to Manu's expertise and judgment on the
>> matter:
>>
>> We should make his reasoning on the importance of deliberately choosing
>> virtual vs private in API-public classes prominent in documentation,
>> wikis, books and other learning materials.
>>
>> It may not be an important enough to justify a large language break, but
>> if Manu says it is genuinely a problem in his industry, we should do our
>> best to alleviate as much as is reasonable.
>
> I think that's a great idea.

Related suggestion.

I know that Walter really doesn't like compiler warnings, and to a large degree I understand his dislike.

However, in this case I think we could do much to alleviate the negative effects of virtual-by-default by making it a compiler warning for a class method to be without an explicit indicator of whether it's to be final or virtual.

That warning would have to be tolerant of e.g. the whole class itself being given a "final" or "virtual" marker, or of tags like "final:" or "virtual:" which capture multiple methods.

The warning could include an indication to the user: "If you're not certain which is preferable, pick final."

The idea would be that it be a strongly enforced D style condition to be absolutely explicit about your intentions final- and virtual-wise.  (If a compiler warning is considered too strong, then the task could be given to a lint tool.)
March 16, 2014
On 3/16/14, 11:46 AM, Joseph Rushton Wakeling wrote:
> Actually, rather the opposite -- I know you understand the arguments
> very well, and therefore I have much higher expectations in terms of how
> detailed an explanation I think you should be prepared to offer to
> justify your decisions ;-)

I literally can't say anything more on the subject than I've already had. I've said it all. I could, of course, reiterate my considerations, and that would have other people reiterate theirs and their opinion on how my pros don't hold that much weight and how my cons hold a lot more weight than they should.

> One of the problems with this particular issue is that probably as far
> as most people are concerned, a discussion was had, people pitched
> arguments one way and the other, some positions became entrenched, other
> people changed their minds, and finally, a decision was made -- by you
> and Walter -- in favour of final by default.

For the record I never decided that way, which explains my surprise when I saw the pull request that adds "virtual". Upon discussing with Walter it became apparent that he made that decision against his own judgment. We are presently happy and confident we did the right thing.

Please do not reply to this. Let sleeping dogs tell the truth.


Thanks,

Andrei

March 16, 2014
Andrei Alexandrescu:

> I literally can't say anything more on the subject than I've already had. I've said it all. I could, of course, reiterate my considerations, and that would have other people reiterate theirs and their opinion on how my pros don't hold that much weight and how my cons hold a lot more weight than they should.

But was the decision taken on the basic of experimental data? I mean the kind of data Daniel Murphy has shown here:

http://forum.dlang.org/thread/lfqoan$5qq$1@digitalmars.com?page=27#post-lg147n:242u14:241:40digitalmars.com

Bye,
bearophile
March 16, 2014
On 03/14/2014 04:31 PM, ponce wrote:
> On Friday, 14 March 2014 at 15:17:08 UTC, Andrei Alexandrescu wrote:
>> Allowing computed qualifiers/attributes would be a very elegant and
>> general approach, and plays beautifully into the strength of D and our
>> current investment in Boolean compile-time predicates.
>>
>
> Bonus points if inout can be replaced that way :)
>
>

It cannot.
March 16, 2014
On 3/13/14, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
> This:
>
> final class A {
>      int i;
>      void f() { ++i; }
>      void g() { ++i; }
>
> }
> pragma(msg, __traits(isFinalFunction, A.g));
> pragma(msg, __traits(isFinalFunction, A.f));

Speaking of final classes, I've ran into this snippet a few weeks ago in src/gc/gc.d:

-----
// This just makes Mutex final to de-virtualize member function calls. final class GCMutex : Mutex {}
-----

But does this actually happen?
March 17, 2014
On 3/16/2014 1:04 AM, Iain Buclaw wrote:
> Indeed other stuff needs to be done, it just so happens that thanks to
> sys.posix's bad design splitting out other modules into ports will be more a
> pain.  But it shows how *no one* in that thread who responded either against the
> first pull, or went off and hijacked the second had a Scooby about the issue
> being addressed.  Didn't even have the curiosity to give alternate suggestions.

The 731 pull added more files under the old package layout.

The 732 added more files to the config system, which I objected to.

I believe my comments were apropos and suggested a better package structure than the one in the PR's.
March 17, 2014
On 17 March 2014 01:25, <7d89a89974b0ff40.invalid@internationalized.invalid>wrote:

> On Sunday, 16 March 2014 at 13:23:33 UTC, Araq wrote:
>
>> I note that you are not able to counter my argument and so you escape to the meta level. But don't worry, I won't reply anymore.
>>
>
> Discussing OO without a context is kind of pointless since there is multiple schools in the OO arena. The two main ones being:
>
> 1. The original OO analysis & design set forth by the people behind Simula67. Which basically is about representing abstractions (subsets) of the real word in the computer.
>
> 2. The ADT approach which you find in C++ std libraries & co.
>
> These two perspectives are largely orthogonal…
>
> That said, I think it to be odd to not use the term "virtual" since it has a long history (Simula has the "virtual" keyword). It would look like a case of being different for the sake of being different.
>
> Then again, I don't really mind virtual by default if whole program optimization is still a future goal for D.
>

Whole program optimisation can't do anything to improve the situation; it is possible that DLL's may be loaded at runtime, so there's nothing the optimiser can do, even at link time.