March 13, 2014
On 3/13/2014 10:07 AM, Xavier Bigand wrote:
> Maybe if changes are really simple a tool can help? Tools are needed for such
> kind of refactoring can be done automatically.

Source code "fixers" give me the heebie-jeebies. Besides, this particular fix needed some judgement.
March 13, 2014
On Wednesday, 12 March 2014 at 22:50:00 UTC, Walter Bright wrote:
> The argument for final by default, as eloquently expressed by Manu, is a good one. Even Andrei agrees with it (!).
>
> The trouble, however, was illuminated most recently by the std.json regression that broke existing code. The breakage wasn't even intentional; it was a mistake. The user fix was also simple, just a tweak here and there to user code, and the compiler pointed out where each change needed to be made.
>
> But we nearly lost a major client over it.
>
> We're past the point where we can break everyone's code. It's going to cost us far, far more than we'll gain. (And you all know that if we could do massive do-overs, I'd get rid of put's auto-decode.)
>
> Instead, one can write:
>
>    class C { final: ... }
>
> as a pattern, and everything in the class will be final. That leaves the "but what if I want a single virtual function?" There needs to be a way to locally turn off 'final'. Adding 'virtual' is one way to do that, but:
>
> 1. there are other attributes we might wish to turn off, like 'pure' and 'nothrow'.
>
> 2. it seems excessive to dedicate a keyword just for that.
>
> So, there's the solution that has been proposed before:
>
>    !final
>    !pure
>    !nothrow
>    etc.

I have no horse in the final race but I would say be wary of becoming too conservative because a client over reacts to a regression. Their reaction sounds unreasonable, especially given how quickly the issue was addressed. Where did the narrative that it was a deliberate breaking change come from?
March 13, 2014
On Thu, Mar 13, 2014 at 02:50:08PM -0700, Walter Bright wrote:
> On 3/13/2014 11:41 AM, Andrei Alexandrescu wrote:
> >2. There's the danger of getting into a design-by-committee rut.
> 
> Back in the early days of the C++ Standards committee, I recall some members negotiating in effect "vote for my proposal and I'll vote for yours". I don't see that as a great way to design a language.
> 
> Democratic committee processes also involve long, and I mean loooong, timespans for making decisions. Like 13 years from C++98 to C++11.

Democratic processes only work well if the least unpopular choice equals the optimal choice. When this is not the case, it consistently produces suboptimal results.

(I say "least unpopular", because it usually turns out that people in a democratic system simply cannot come to an agreement, so the only way forward is to find a choice that displeases everyone the least. This leads to disappointing results when it comes to technical design.)


T

-- 
"I'm not childish; I'm just in touch with the child within!" - RL
March 13, 2014
On 03/13/2014 02:32 PM, Steven Schveighoffer wrote:
>
> The one I would really like to see is logical OR. There is no easy way
> around this, one must come up with convoluted mechanisms that are much
> harder to design, write, and understand than just version(x || y)

version(A) version=AorB;
version(B) version=AorB;
version(AorB){ }

March 13, 2014
"Daniel Murphy" <yebbliesnospam@gmail.com> writes:

> "Don"  wrote in message news:ekymfpqyxasvelcixrjp@forum.dlang.org...
>
>> I agree completely.
>>
>> Some things that really should be fixed, don't get fixed because of a paranoid fear of breaking code. And this tends to happen with the issues that can give nice warning messages and are easy to fix...
>>
>> Yet there are still enough bugs that your code breaks every release anyway. We need to lose the fantasy that there is legacy code which still compiles. Anything more than a year or so old is broken already.
>
> As usual I agree with every single thing in this post, and Sean's. Regressions are bad but have nothing to do with using slow, controlled deprecation to make the language better.

I add my +1 to this side of the argument.  Performance matters.  D is of interest to me as a language that is clean but performs well out of the box.  The harder it is to make it perform well, the more we might as well continue to use C++.  I've fixed multiple preformance problems involving virtual functions being used where they don't belong.  I want to see final by default for performance.

I also want to see final by default as I work in an area where many APIs are created by people who are trying things out, rather than designing software for the long term.  Invariably, some of these APIs will linger and be very hard to fix down the road.  I'd *much* rather these maintenance headaches not be virtual.

I also second the point that a controlled deprecation cycle is vastly different from accidental breakage.  It can be planned for as long as the communication happens.  It might be very useful to have a roadmap page that lists every deprecation cycle that is planned or ongoing.

Jerry
March 13, 2014
On 3/13/2014 3:21 PM, Timon Gehr wrote:
> On 03/13/2014 02:32 PM, Steven Schveighoffer wrote:
>>
>> The one I would really like to see is logical OR. There is no easy way
>> around this, one must come up with convoluted mechanisms that are much
>> harder to design, write, and understand than just version(x || y)
>
> version(A) version=AorB;
> version(B) version=AorB;
> version(AorB){ }
>

If you're writing things like that, it's still missing the point. The point is not to find workarounds, but to rethink just what feature is being version'd on.

For example, suppose it's wrapping a call to SomeWackyFunction:

version (Linux)
    SomeWackyFunction();
else version (OSX)
    SomeWackyFunction();
else
    ... workaround ...

Execrable answer:

    version (Linux) version=LinuxOrOSX;
    version (OSX) version=LinuxOrOSX;
    ...
    version (LinuxOrOSX)
	SomeWackyFunction();
    else
        ... workaround ...

This is execrable because LinuxOrOSX:

1. has no particular relationship to SomeWackyFunction()
2. makes for confusion if LinuxOrOSX is used also to version in other things
3. makes for what do I do if I add in FreeBSD? Rename to LinuxOrOSXOrFreeBSD ? yeech


Better answer:

    version (Linux) version=hasSomeWackyFunction;
    version (OSX) version=hasSomeWackyFunction;
    ...
    version (hasSomeWackyFunction)
	SomeWackyFunction();
    else
        ... workaround ...

At least this is maintainable, though it's clumsy if that code sequence appears more than once or, worse, must be replicated in multiple modules.

Even better:

    --------
    import wackyfunctionality;
    ...
    WackyFunction();
    --------
    module wackyfunctionality;

    void WackyFunction() {
        version (Linux)
  	    SomeWackyFunction();
        else version (OSX)
            SomeWackyFunction();
        else
            ... workaround ...
    }
    --------

Simple, maintainable, easy on the eye.


March 13, 2014
On 03/13/2014 11:43 PM, Walter Bright wrote:
>>
>> version(A) version=AorB;
>> version(B) version=AorB;
>> version(AorB){ }
>>
>
> If you're writing things like that, it's still missing the point. ...

Unless the point is to demonstrate that it is not too convoluted. ;)

March 13, 2014
On Thursday, 13 March 2014 at 21:50:10 UTC, Walter Bright wrote:
> On 3/13/2014 11:41 AM, Andrei Alexandrescu wrote:
>> 2. There's the danger of getting into a design-by-committee rut.
>
> Back in the early days of the C++ Standards committee, I recall some members negotiating in effect "vote for my proposal and I'll vote for yours". I don't see that as a great way to design a language.
>
> Democratic committee processes also involve long, and I mean loooong, timespans for making decisions. Like 13 years from C++98 to C++11.

To be pedantic, there was a TC released in 2003.  And many of the
C++11 features were available years ahead of time from all the
usual library sources.  But I agree that the ISO process isn't
fast.  In fact, I think that's an actual goal, as the industries
that depend on these standards are slow-moving as well.
March 13, 2014
On 3/13/2014 4:10 PM, Sean Kelly wrote:
> To be pedantic, there was a TC released in 2003.  And many of the
> C++11 features were available years ahead of time from all the
> usual library sources.  But I agree that the ISO process isn't
> fast.  In fact, I think that's an actual goal, as the industries
> that depend on these standards are slow-moving as well.

Of course. Slow is not always a bad thing.
March 14, 2014
On 3/13/14, 3:21 PM, Timon Gehr wrote:
> On 03/13/2014 02:32 PM, Steven Schveighoffer wrote:
>>
>> The one I would really like to see is logical OR. There is no easy way
>> around this, one must come up with convoluted mechanisms that are much
>> harder to design, write, and understand than just version(x || y)
>
> version(A) version=AorB;
> version(B) version=AorB;
> version(AorB){ }

From a project at work:

// Import the appropriate built-in #define menagerie
version (gcc4_7_1) {
  version = gnu;
  import defines_gcc4_7_1, defines_gxx4_7_1;
}
version (gcc4_8_1) {
  version = gnu;
  import defines_gcc4_8_1, defines_gxx4_8_1;
}
version (clang3_2) {
  version = clang;
  import defines_clang3_2, defines_clangxx3_2;
}
version (clang3_4) {
  version = clang;
  import defines_clang3_4, defines_clangxx3_4;
}
version (clangdev) {
  version = clang;
  import defines_clangdev, defines_clangxxdev;
}
...
// Compiler-dependent extra defines
version (gnu) {
  ...
}
version (clang) {
  ...
}


yum

Andrei