Whole source-tree statefull preprocessing, notion of a whole program
Vladimir Panteleev via Digitalmars-d
digitalmars-d at puremagic.com
Sat Apr 8 10:57:11 PDT 2017
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
More information about the Digitalmars-d
mailing list