On Saturday, 8 April 2017 at 14:20:49 UTC, Boris-Barboris wrote:
Looks like your current implementation does not go in that direction, seeing as it uses properties for field access.

Am i mistaken in assumption that such simple getter property will be optimized to direct field access? Anyways, that's minor detail.

I don't know the type of CONF.root, but from the usage syntax in your example, it looks like an associative array. Associative array lookup will be slower than simply accessing a variable.

Individual components' configuration can be delegated to their components; their modules could contain public struct definitions that you can add to the global Config struct, which describes the configuration of the entire application. I've used this pattern successfully in some projects, incl. Digger: https://github.com/CyberShadow/Digger/blob/master/config.d#L31-L36

Ok, that's nice, but it still requires manual inclusion of such field into global config struct.

Yes; in my opinion, I think that's desirable because it is aligned with the unidirectional flow of information from higher-level components to lower-level ones, and does not impose a particular configuration framework onto the lower-level components (they only need to declare their configuration in terms of a POD type).

Some "compile-time callback" system still would scale better in my opinion.

A similar effect can be achieved by allowing components to register themselves in a static constructor (not at compile-time, but at program start-up).

I understand that you seem to be looking for a way to change types (definitions in general) inside modules you import. This is problematic from several aspects, such as other modules depending on that module may find that the definitions "change under their feet".

As expected since class that allows itself to be modified in compile-time, always does so explicitly via mixin. Most of the times such manipulation is used to extend functionality (add field, plugin, method) without removing or modifying existing ones. And if the names conflict, we get nice compile-time error anyways.

Then you have problems such as the instance size of a class changing depending on whether the code that requires the instance size is seen by the compiler before the code that modifies the instance size. I think it would cause complicated design problems that limit the scalability of the language. Even without such features, DMD had to go through a number of bugs to iron out the correct semantics of evaluating types (e.g. with "typeof(this).sizeof" inside a struct declaration, or recursive struct template instantiations).

In D, once a type is declared and its final curly brace is closed, you will know that its definition will remain the same from anywhere in the program.

That's kinda my point - definition needs to stay the same because it's built by compiler as many times as there are transtaltion units, because evil old C grandpa.

I think this is not about technical limitations, but intentional design choices. Allowing types to be modified post-declaration invalidates many contracts and assumptions that code may have, and make it harder to reason about the program as a whole. Compare with e.g. INTERCAL's COMEFROM instruction.

D's answer to partial classes is UFCS, however this does not allow "adding" fields, only methods.

Adding fields, or, generally, objects \ collections of objects, is the main use case. Adding methods in my experience is rare scenario.

UFCS is widely used in D for component programming:

http://www.drdobbs.com/architecture-and-design/component-programming-in-d/240008321

Reply via email to