September 04, 2019
I started to write up some thoughts on getting changes we want into the language and reducing the pain. It is is similar to the --preview switch, except it is about grouping changes to make the language we want.

It was recently asked how the transition to dip 1000 so more are making use of the expected new default. My thought is to include it in a v3 release of the compiler, which would include safe by default, etc.

Following is the original thoughts written for an audience outside the D community. I'm tired of trying to review it.


D has a history and gone through some growing pains. Progressing past certain language design is a challenge to maintain compatibility with previous written code. Java has had to maintain its byte code compatibility along with the language. D had made a transition to transitive const and immutable when it switched to v2, which lead to a fracturing of the language (D1 also had a fracture with Tango, while D2 eventually was united when Tango was ported).

Several additional features of the language have been added and many in the community would prefer the defaults to change. Many of these features are also limited in us because until recently the standard libraries did not use those features. Another side to this is changes to the standard library can be challenging when the api needs changed.

Progressing a language is challenging as older techniques can add to complexity and interfere with other desired improvements. This usually means there are two choices, depression or deal with being limited in how things are. I wanted to put down some depreciation thoughts to specific changes for D.

• safe and no throw by default
• auto decoding in utf8

The challenges with changing the default is that it creates a breaking change where all code won't compile. Walter has generally been against compiler switches to change default behavior, it makes many different dialects to the language. C# has chosen to utilize a setting found in the project file to change the nullable behavior. There is however recent precedence to use compiler switches to progress the D language with breaking changes.

A compiler switch could be added to make the compiler operate with a new set of defaults, this would mean a single switch instead of one default. However I think this might be too global of a change. Instead I think that it should apply to the smallest compilation unit, the module. A module could be annotated with the language version, `@__LanguageVersion(2):` and this would instruct the compiler to select defaults of that version.

Auto decoding is different as it is a library solution. In this case the availability is what matters, the standard libraries needs written with the new desired behavior, new defaults don't specifically create a need to use them, but it is important to support their use in the library.

Much like auto decoding, this is more about the library support than having the compiler dictate behavior. If you pass a not-null to a method that method does not care. But if the method only takes non-null, then you'll need to call it approximately. D hasn't really figured out its strategy for not null method signatures. Thus I just want to say it would probably be good for it to be the default and a nullable type come into play.

All of this makes for a ton of work. It's not like this would be completed and released over night providing a platform for existing solutions to migrate to. Instead only portions would be completed and those portions would need to be tested and tweaked. This means a strategic rollout must happen to make it a reality.

This idea of using a compiler switch to build out a change in the language is not new. I lived through the v1 to v2 transition where both versions were initially in the same compiler and only a version switch away.

To learn from the past it must be possible to use libraries in either version. That is to say you aren't applying semantics which don't match the semantics of the other codebase. This means that for every attribute needs to have an opposite (something saught after before).

It is possible that libraries will want to make better use of these new defaults in order to make the usage more prevalent in the ecosystem. This could be a breaking change to their api, so they should make the appropriate mitigations. Phobos, the standard library is different however.

Many of D libraries come as source code instead of binary blobs. Since the compiler distributes the library and in need of compiling both sets of defaults it is important that it comes with support for both api designs. It also defines what a string range is meaning it should remain consistent with itself. Replicating this ecosystem under std.v3 seem reasonable, as suggested by Andrei.

It is important to note this isn't a replacement for depreciation and other language cleanup. Semantics must remain the same so we don't add or remove functionality which does not get added or removed in both versions. Libraries will need to choose which version to build for and supply the needed api they desire to expose. This does create a second ecosystem which Walter is concerned of, but since language semantics are the same the libraries are still usable in both versions.