My attribute-by-default proposal. Also dmd 2.090 came out.

Posted 2020-01-13

I don't think we should change the attribute defaults. Instead, make the foo: at the top of the file work well.

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on


I'm done with jni.d for now. The code generator doesn't recreate the whole Java class hierarchy in D since I had trouble getting all the pieces work with my lazy separate compilation (I may write more about this later), so I instead flattened the hierarchy into final classes that can be library casted to interfaces as needed.

It still takes a while to compile things like the whole Android framework... but it takes < 4 GB of RAM so at least it is reasonably doable.

I am sure I'll be back to all this but for now I need to move on. It works! Not with every perfect feature, but with all the key points.


My new websocket client implementation should basically work now. It will be formally released once I make my decision on modularization (will I make it separate or keep copy/pasting between cgi and http?)

My attribute proposal - no changes to defaults

The argument over @safe-by-default continues, and you know, I kinda feel - in the same sense of settling for great rather than perfect with jni.d last week - we should go for another solution with attributes, at least for a while. Here's my proposal:

  • We add inverses for everything. nothrow gets throws, pure gets impure, etc.

    This gives us control to undo one setting at a time.

  • We make a rule so all these descend into child scopes.
    module foo;
    pure nothrow:
    void foo() {} // pure nothrow here
    struct A {
    	void bar() {} // pure nothrow here too!

    This allows one declaration at the top of the module actually apply to everything in it; effectively changing the defaults on a per-module level.

  • Templates do NOT pick up attributes that can be inferred from the scope.
    module foo;
    void t()() {} // NOT @safe, instead inferred

    If you specifically want a @safe attribute to apply to a template, it must be written right on it:

    module foo;
    @safe void t()() {} // IS specifically @safe since it was written right on it.

    I'm undecided on which bucket @safe {} falls into. I lean toward that applying to templates same as if you wrote it directly on it. So this exemption rule only applies to foo: settings.

    Note that I said "inferred attribute", if a template wouldn't normally infer the given thing, it should still be attached. e.g. UDAs.

    Basically, foo: changes the default going forward, but if the default behavior is to infer it, it is still inferred.

I think if we hit those three points, we get all the benefits of changing the defaults with only a small fraction of the breakage (this is a change from the current behavior still, but a very small one - and what many people assume the current behavior is anyway).

As for the specific ways to invert attributes... like meh, I don't care. I just want it to be possible.

Then our libs can make the very small effort of writing whatever stuff: at the top to opt into these things and just forget about it. Much easier than it is now. And then it can propagate out through the community ecosystem and possibly make the choice of defaults moot, or at least make it more palatable to revisit in some time in the future.

Code reviewers might require a certain set in each module too as an organizational policy, similar to how things would require use strict in other languages to get a module merged. It'd be a very easy check to do given the above rules.