Whole source-tree statefull preprocessing, notion of a whole program

Boris-Barboris via Digitalmars-d digitalmars-d at puremagic.com
Sat Apr 8 13:37:33 PDT 2017


On Saturday, 8 April 2017 at 17:57:11 UTC, Vladimir Panteleev 
wrote:

> 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).
...
> 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).

   That is definetly possible and, I would say, trivial, and this 
is the most popular way. However, any run-time registration 
implies run-time collections to iterate over, with obvious 
performance drawbacks (minor ones in this case). We are not using 
the information we have a-priory, in compile time, and make CPU 
pay for it instead (either because we are too lazy (too busy) to 
update sources of higher-level components (while making them a 
mess), or just because our language lacks expressibility, wich is 
my point).
   I side with another set of virtues. Source code consists of 
files. Files contain related data, concepts, functionality, 
whatever. Relations between those entities must by no means be 
unidirectional. What direction can you impose to concept "For 
every configurable entity, be that package, module, or class, I 
need to have fields in global configuration singleton"?
   IMO program has good architecture, when during extensive 
development for arbitrary group of programmers it takes little 
time and effort to make usefull changes. It is achieved by 
extensive problem field research, use of abstraction to fight 
complexities, yada yada... Part of it is to make sure, that you 
can extend functionality easily. Adding new subclass in one file 
and registering it in two others is not hard. But there is no 
fundamental reason for it to not be easier: just add subclass and 
slap some fancy attribute on it, or add some preprocessor-related 
field or function in it's body.
   Onde-directional flow is a consequence, not a principle. It's 
because languages were made this way we are used to it. When 
high-level concept or idea willingly implies feedback from it's 
users, there is little reason to forbid it. Especially when it 
actually improves development iteration times, lowers risks of 
merge conflicts etc.

   Look at this mess:
https://github.com/Boris-Barboris/AtmosphereAutopilot/blob/master/AtmosphereAutopilot/GUI/AutoGui.cs#L190
   It's caching code for some C# reflection-based GUI I wrote some 
time ago, that defines attribute to mark class fields with in 
order to draw them in pretty little debug window. Why do I have 
to do this? I've got all information right in the source. All 
classes that will be drawn using this GUI module are there, in 
text, accessible to build system. Why can't I just write clean 
code, that doesn't involve double or tripple associative array 
dispatch on runtime-reflected list of subclasses and 
attribute-marked fields? Answer is simple - language lacks 
expressibility. I provide drawing functionality in my module. It 
is generic, it is virtuous, it is concentrated in one file, it 
speeds up development. However, it needs to see it's client, 
beneficient, in order to draw him. And it just doesn't. Because 
C#, and you need to do runtime reflections. Yet again, by 
throwing away information you already have and making CPU 
reconstruct it again during runtime, over and over.
   Yes, all things I describe can be done efficiently by writing a 
lot of boilerplate code or using some text-templating magic. I 
just don't see why languages can't have that functionality 
built-in.

> 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).

I agree. I think such mechanisms must be applied very early, 
hence "premixin".

> 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.

   I still don't see the problem. Declaration will contain 
constructs that indicate that it will be changed, like, for 
example, "premixin" that iterates over array and adds fields. I 
have no doubt human can read this allright.
   Indeed, question of ordering is important.
   Well, we have goto, it's not like sky dropped down on us. 
COMEFROM breaks logical time flow. I only want two-staged 
preprocessing, when in first stage I can create and manipulate 
some simple, visible to preprocessor state, even if it consists 
of only immutable base types and arrays of those, and then being 
able to use that state as immutable variables in next stages we 
already have. We already can populate class with fields from 
immutable string array. All I'm wanting is ability to populate 
this array using preprocessor directives from across whole 
compiled program, before all other complex stuff starts. I think 
that would be beautiful.

>
> UFCS is widely used in D for component programming:
>
> http://www.drdobbs.com/architecture-and-design/component-programming-in-d/240008321

I'm not stating the opposite, just sharing what I encountered on 
work or during programming for fun - I mostly needed to add 
fields. People may feel otherwise, but I don't see this concept 
harming them in any way.



More information about the Digitalmars-d mailing list