Please suggest use-cases for introspective code generation

This is a discussion on Please suggest use-cases for introspective code generation within the c++ forums in Programming Languages category; Hi folks, I'm looking for a few more interesting use cases to help validate and mature the design / implementation, and use as case studies in the documentation, of a C++ introspective preprocessor / code generator. A few examples to get you started (hopefully not enough to get you bored): - auto-generation of object serialisation / deserialisation member functions - based on operator<<(std: stream&, ) / binary / XML - run-time execution based on textual identifier/params - member functions ala std::string get_member_variable(const char identifier[]) const; std::string call_member_function(const char fn_identifier, std::vector<const std::string& args); std::string call_member_function(const char fn_identifier, std::vector<const std::string& args) const; ...

Go Back   Application Development Forum > Programming Languages > c++

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 09-05-2008, 12:23 AM
Tony Delroy
Guest
 
Default Please suggest use-cases for introspective code generation

Hi folks,

I'm looking for a few more interesting use cases to help validate and
mature the design / implementation, and use as case studies in the
documentation, of a C++ introspective preprocessor / code generator.

A few examples to get you started (hopefully not enough to get you
bored):

- auto-generation of object serialisation / deserialisation member
functions
- based on operator<<(std:stream&, ) / binary / XML

- run-time execution based on textual identifier/params
- member functions ala
std::string get_member_variable(const char identifier[]) const;
std::string call_member_function(const char fn_identifier,
std::vector<const std::string& args);
std::string call_member_function(const char fn_identifier,
std::vector<const std::string& args) const;
( requires operator>> able to stream into actual argument types )
- class/object registries

- abstract interfaces for the union or intersection of members in an
arbitrary list of concrete class
- associated factories

- abstract interfaces for the members in a template (example at end of
email)
- associated code for polymorphic access to existing object, factory
method

- incorporation of code from external utilities - e.g. generation of
perfect hash-tables, database metadata etc.

....

Anyway, creative but practical suggestions very much appreciated...

Regards,

Tony

--- compile-time to run-time polymorphic handover ---

just a quick example of the kind of techniques I'm aiming to support -
nothing new or exciting about the below - but automating generation
makes it practical on a larger scale...

#include <iostream>

// > generated
struct Abstract_C {
virtual ~Abstract_C() { }
virtual double add(double) const = 0;
};
// < generated

template <typename A>
struct C {
C(const A& a) : a_(a) { }
double add(double b) const {
std::cout << __PRETTY_FUNCTION__ << '\n';
return a_ + b;
}

private:
A a_;

// > generated
struct AbstractPtr : public Abstract_C {
AbstractPtr(C* p) : p_(p) { }
double add(double b) const { return p_->add(b); }
private:
C* p_;
};

public:
AbstractPtr* accessor() { return new AbstractPtr(this); }

private:
struct Abstract : C, public Abstract_C {
Abstract(const A& a) : C(a) { }
double add(double b) const { return C::add(b); }
};

public:
static Abstract_C* factory(const A& a) { return new Abstract(a); }
// < generated
};

int main()
{
C<int> c1(-5);
assert(c1.add(10) == 5);

Abstract_C* p_c1 = c1.accessor();
assert(p_c1->add(-5) == -10);
delete p_c1;
assert(c1.add(100) == 95); // c1 still exists...

Abstract_C* p_c2 = C<float>::factory(12.5);
assert(p_c2->add(29.5) == 42);
delete p_c2;
// no c2...
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #2  
Old 09-05-2008, 05:34 AM
Le Chaud Lapin
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
> A few examples to get you started (hopefully not enough to get you
> bored):


I must admit that I am having hard time understanding exactly what is
it that you are offering, based on your code sample.

> - auto-generation of object serialisation / deserialisation member
> functions
> - based on operator<<(std:stream&, ) / binary / XML


IMHO, there is no such thing as auto-generation of any type of
serialization. C++ (and pseudo-C++) programmers the world over have
been trying in vain to add introspection to C++ with no success. The
reason is that it is not possible. Computers cannot read. A thinking
being (person) will always need to indicate whether variable should be
serialized or not, and once that indication becomes necessary all bets
are off - the brain energy would have just as well been spent in
writing the serialization code.

> - run-time execution based on textual identifier/params
> - member functions ala
> std::string get_member_variable(const char identifier[]) const;
> std::string call_member_function(const char fn_identifier,
> std::vector<const std::string& args);


Why?

> std::string call_member_function(const char fn_identifier,
> std::vector<const std::string& args) const;
> ( requires operator>> able to stream into actual argument types )
> - class/object registries


Why?

> - abstract interfaces for the union or intersection of members in an
> arbitrary list of concrete class
> - associated factories


Why?

> - abstract interfaces for the members in a template (example at end of
> email)
> - associated code for polymorphic access to existing object, factory
> method


Why?

> - incorporation of code from external utilities - e.g. generation of
> perfect hash-tables, database metadata etc.


Tomorrow, when I wake up, I am going to use Google to find the crème
de la crème of open-source projects, the top 1% of 1% of 1%. I am
going to use my development system to create a Super Project that
contains say, 10 of these ultra-high quality projects. I will mix
these projects together in a common directory, and offer each of them
a warm blanket, a teddy bear, hot chocolate, and The Communist
Manifesto by Marx and Engels so that they have something to read while
they enjoy each other's company in harmony with each other. I will
then hit the compile button, stand back, and watch the social magic.
Surely the whole concoction will be at least as beautiful, functional,
useable, as any of the individual parts. If it is not, I will
endlessly refactor the code until I at least see some blinking lights.

Software, and other primitives of science and engineering, are
inanimate artifacts, not people.

-Le Chaud Lapin-


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #3  
Old 09-05-2008, 01:13 PM
Tony Delroy
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 5, 6:34 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
> On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
>
> I must admit that I am having hard time understanding exactly what is
> it that you are offering, based on your code sample.


Hi. Thanks for taking the time to write. Actually, I'm not offering
anything. I'm asking for something: suggestions.

> > - auto-generation of object serialisation / deserialisation member
> > functions
> > - based on operator<<(std:stream&, ) / binary / XML

>
> IMHO, there is no such thing as auto-generation of any type of
> serialization. C++ (and pseudo-C++) programmers the world over have
> been trying in vain to add introspection to C++ with no success. The
> reason is that it is not possible. Computers cannot read. A thinking
> being (person) will always need to indicate whether variable should be
> serialized or not, and once that indication becomes necessary all bets
> are off - the brain energy would have just as well been spent in
> writing the serialization code.


Actually, it's not that hard. OpenC++ is one example. In fact, it's
more systematic and complex than what I'm doing. I believe its
problem is that it's slow work injecting new code or modifying old if
you're forced to do it at the parsed tree level, rather than by
writing a big chunk of raw textual source code in the familiar
everyday format.

To match your one brief diversion into specifics, in my tool whether
to include a variable can be controlled by a mixture of a default and
an explicit override. This is most easily achieved by adding to the
multimap of attributes associated with each elements in the
declaration tree:

...
int x `serialise = false`;
...

These attributes can be easily inspected during code generation.

Anyway, how to achieve the introspective preprocessing it is not what
I'm interested in discussing - it's a done deal. What I am interested
in is finding a few more useful applications of the tool with which to
mature and highlight capabilities.

> > - run-time execution based on textual identifier/params
> > - member functions ala
> > std::string get_member_variable(const char identifier[]) const;
> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args);

>
> Why?


I would hope you're not serious, but anyway: this is a simplistic but
powerful step towards run-time control of a C++ system.

> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args) const;
> > ( requires operator>> able to stream into actual argument types )
> > - class/object registries

>
> Why?


....as above...

> > - abstract interfaces for the union or intersection of members in an
> > arbitrary list of concrete class
> > - associated factories

>
> Why?


It basically lets you trivially throw together a list of types that
you want to manage polymorphically, either limiting yourself to the
commonality or a fat interface. Why? Why? Again, I can only hope
your experience has suggested some use for polymorphism.

> > - abstract interfaces for the members in a template (example at end of
> > email)
> > - associated code for polymorphic access to existing object, factory
> > method

>
> Why?


Handover from compile-time to run-time polymorphism is extremely
important in large systems. Techniques like those in Modern C++
Design clearly have enormous potential to deliver high performance and
extremely customisable objects allowing one implementation to embrace
arbitrary combinations of policies representing distinct design
choices. Really, really nice. But if you have a large system and
need to pass types across system interfaces, you find writing a
function to work on a policy-templated data type is a non-trivial
commitment. You either have to make your function a template and
explose the interface, creating recompilation coupling (i.e. opposite
characteristics of pImpl idiom) or achieve some compile-time to run-
time handoff. That's what the technique mentioned above automates.

> > - incorporation of code from external utilities - e.g. generation of
> > perfect hash-tables, database metadata etc.

>
> Tomorrow, when I wake up, I am going to use Google to find the crème
> de la crème of open-source projects, the top 1% of 1% of 1%. I am
> going to use my development system to create a Super Project that
> contains say, 10 of these ultra-high quality projects. I will mix
> these projects together in a common directory, and offer each of them
> a warm blanket, a teddy bear, hot chocolate, and The Communist
> Manifesto by Marx and Engels so that they have something to read while
> they enjoy each other's company in harmony with each other. I will
> then hit the compile button, stand back, and watch the social magic.
> Surely the whole concoction will be at least as beautiful, functional,
> useable, as any of the individual parts. If it is not, I will
> endlessly refactor the code until I at least see some blinking lights.
>
> Software, and other primitives of science and engineering, are
> inanimate artifacts, not people.


What was that all about? You think I'm off dreaming my little
dreams? Fine, I'm not interested in changing your mind, just
requesting suggestions from anyone kind enough to offer such, and
replying to you primarily because I don't want them discouraged.
Secondarily because I'm pedantic enough to always want the last word.
Time will tell.

( Just in case your final flight of fancy was provoked by the common
confusion over the term "perfect hash table" I'll mention it has a
well-defined non-romantic down-to-earth technical meaning: not two
keys hash to the same bucket. )

Regards,

Tony


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #4  
Old 09-05-2008, 01:14 PM
Mathias Gaunard
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:

> - run-time execution based on textual identifier/params
> - member functions ala
> std::string get_member_variable(const char identifier[]) const;
> std::string call_member_function(const char fn_identifier,
> std::vector<const std::string& args);
> std::string call_member_function(const char fn_identifier,
> std::vector<const std::string& args) const;
> ( requires operator>> able to stream into actual argument types )
> - class/object registries


I really fail to see the point of this.
That kind of information would be much more useful at compile-time,
and it wouldn't bloat code size for no reason.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #5  
Old 09-05-2008, 06:28 PM
Tony Delroy
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
>
> > - run-time execution based on textual identifier/params
> > - member functions ala
> > std::string get_member_variable(const char identifier[]) const;
> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args);
> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args) const;
> > ( requires operator>> able to stream into actual argument types )
> > - class/object registries

>
> I really fail to see the point of this.
> That kind of information would be much more useful at compile-time,
> and it wouldn't bloat code size for no reason.


Hi Mathias,

Thanks for taking the time to respond, and asking about this. I'm
certainly not suggesting every program wants to maintain all this
baggage, just that some programs, for anything from a single class
with lots of data members through an entire subsystem or three, may
find it useful. Applications:
- facilitating access to C++ functionality from scripting languages;
- setting variables or modal states during parsing of configuration
files;
- last-resort but powerful run-time control of a C++ system to help
nurse it through production issues or correct bogus data (may well be
impractical - and unmaintainable to attempt - to provide anything like
the same pervasiveness of control through explicitly coded points of
access);
- interactive use of a system (for some kinds of objects, a great way
to learn how to use them is to create one then poke and prod it to see
how it responds. This often works well in say tcl/tk and Ruby: far
more tangible and immediate than C++'s "add a few couts, re-compile,
re-run, search through all the old couts to find the new, check the
doco to see what you're allowed to try next" cycles);
- automated testing.

Re your suggestion of utility at compile time: certainly got me asking
myself if I've covered all the bases, as I'm not quite sure what
you're thinking of. So a bit of background, and I hope you'll comment
further....

The preprocessor in question performs on-the-fly compilation of
arbitrary C++, so any code that's useful to call at compile time can
be compiled and called in a more traditional C++ style. Functions
like those above are relatively inefficient, sloppy run-time
mechanisms. That's fine for limited applications like those mentioned
above, but not generally desirable when avoidable. Also note that the
functions suggested above are of the "get me the value of the variable
called X", or "get me the result of calling function Y with argument A
and B" which make sense in a running system, but might not at compile
time. For example, "Image::get_background_colour()" isn't much use
without a loaded Image object.

Apologies if I've failed to address your point.

Regards,

Tony


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #6  
Old 09-06-2008, 10:22 AM
Mathias Gaunard
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On 6 sep, 00:28, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
> On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote:
>
> > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:

>
> > > - run-time execution based on textual identifier/params
> > > - member functions ala
> > > std::string get_member_variable(const char identifier[]) const;
> > > std::string call_member_function(const char fn_identifier,
> > > std::vector<const std::string& args);
> > > std::string call_member_function(const char fn_identifier,
> > > std::vector<const std::string& args) const;
> > > ( requires operator>> able to stream into actual argument types )
> > > - class/object registries

>
> > I really fail to see the point of this.
> > That kind of information would be much more useful at compile-time,
> > and it wouldn't bloat code size for no reason.

>
> Hi Mathias,
>
> Thanks for taking the time to respond, and asking about this. I'm
> certainly not suggesting every program wants to maintain all this
> baggage, just that some programs, for anything from a single class
> with lots of data members through an entire subsystem or three, may
> find it useful. Applications:
> - facilitating access to C++ functionality from scripting languages;
> - setting variables or modal states during parsing of configuration
> files;
> - last-resort but powerful run-time control of a C++ system to help
> nurse it through production issues or correct bogus data (may well be
> impractical - and unmaintainable to attempt - to provide anything like
> the same pervasiveness of control through explicitly coded points of
> access);
> - interactive use of a system (for some kinds of objects, a great way
> to learn how to use them is to create one then poke and prod it to see
> how it responds. This often works well in say tcl/tk and Ruby: far
> more tangible and immediate than C++'s "add a few couts, re-compile,
> re-run, search through all the old couts to find the new, check the
> doco to see what you're allowed to try next" cycles);
> - automated testing.
>
> Re your suggestion of utility at compile time: certainly got me asking
> myself if I've covered all the bases, as I'm not quite sure what
> you're thinking of. So a bit of background, and I hope you'll comment
> further....


template<typename T>
struct reflection
{
};

template<>
struct reflection<MyClass>
{
typedef mpl::map<
mpl:air<
mpl::string<'f', 'o', 'o'>,
some_functor_type
>,

...
> member_variables;


typedef mpl::map<
mpl:air<
mpl::string<'b', 'a', 'r'>,
some_other_functor_type
>,

...
> static_variables;


typedef mpl::map<
mpl:air<
mpl::string<'b', 'a', 'z'>,
yet_another_functor_type
>,

...
> member_functions;


typedef ... static_functions;

typedef mpl::map<
mpl:air<
mpl::string<'t', 'y', 'p', 'e'>,
TypeInQuestion
>,

...
> typedefs;


typefef mpl::vector<
Base1,
...
> bases;

};

It's only types, so it adds no overhead in size. It also adds no
overhead at runtime if you want to make use of it.
If the information is needed at runtime, you're free to copy parts of
it.
Making the information compile-time allows it to be much more useful
since the compiler is aware of the typing system.

The code before is just an example.
Member variables would expose a functor that takes an object and
returns the member. Static variables would expose a nullary functor
that takes nothing and returns the static variable. Of course, the
functors would expose the returned type, i.e. the type of the member.
Member and static (member) functions are more complicated, though,
since there can be multiple overloads, templates, etc. A solution
would be to expose simple functors that behaves exactly like the
combination of all overloads, and expose those overloads with the
result_of protocol. It however doesn't really expose the various
signatures. You may think of a way to mangle a signature using
metaprogramming so that more advanced uses can be made.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #7  
Old 09-06-2008, 12:22 PM
Tony Delroy
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
>
> > - run-time execution based on textual identifier/params
> > - member functions ala
> > std::string get_member_variable(const char identifier[]) const;
> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args);
> > std::string call_member_function(const char fn_identifier,
> > std::vector<const std::string& args) const;
> > ( requires operator>> able to stream into actual argument types )
> > - class/object registries

>
> I really fail to see the point of this.
> That kind of information would be much more useful at compile-time,
> and it wouldn't bloat code size for no reason.


Another scenario's just came to mind. If someone's written an
application in VB/Access, and the user says "I want to be able to
enter a query", then they say "yeah, just type it in using this
notation called SQL and I'll spit out all the results for you". The C+
+ programmer with all their data sitting snug in a few STL containers
might have been feeling smug about their performance, but that user
request will be a lot more hassle for them. Of course they could
start using a database, but that's got downsides and may be overkill.
A reasonable query capability can be facilitated by functions like
those above, providing run-time access keyed on identifier for objects
from the containers....

Regards,
Tony


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #8  
Old 09-06-2008, 12:29 PM
Mathieu Mazerolle
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 5, 2:34 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
> On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
> IMHO, there is no such thing as auto-generation of any type of
> serialization. C++ (and pseudo-C++) programmers the world over have
> been trying in vain to add introspection to C++ with no success. The
> reason is that it is not possible. Computers cannot read. A thinking
> being (person) will always need to indicate whether variable should be
> serialized or not, and once that indication becomes necessary all bets
> are off - the brain energy would have just as well been spent in
> writing the serialization code.


Introspection is very useful, and has applications such as binding C++
to scripting languages, marshalling objects for RPC, and debugging. In
fact, if your compiler did not generate introspective information about
your program, your debugger would not be very useful.

It should be a simple matter to define a standard way of inspecting the
static object model and type system of a C++ program. Why has this not
been done yet?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #9  
Old 09-06-2008, 04:24 PM
Tony Delroy
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 6, 11:22 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 6 sep, 00:28, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
> > On Sep 6, 2:14 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> > > On 5 sep, 06:23, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:

>
> > > > - run-time execution based on textual identifier/params
> > > > - member functions ala
> > > > std::string get_member_variable(const char identifier[]) const;
> > > > std::string call_member_function(const char fn_identifier,
> > > > std::vector<const std::string& args);
> > > > std::string call_member_function(const char fn_identifier,
> > > > std::vector<const std::string& args) const;
> > > > ( requires operator>> able to stream into actual argument

types )
> > > > - class/object registries

>
> > > I really fail to see the point of this.
> > > That kind of information would be much more useful at compile-time,
> > > and it wouldn't bloat code size for no reason.

>
> > [...] I'm not quite sure what
> > you're thinking of. So a bit of background, and I hope you'll comment
> > further....

>
> template<typename T>
> struct reflection { };
>
> template<>
> struct reflection<MyClass>
> {
> typedef mpl::map<
> mpl:air<
> mpl::string<'f', 'o', 'o'>,
> some_functor_type
> >,

> ...
> > member_variables;

>
> [ ...snipped by Tony... ]
> };
>
> It's only types, so it adds no overhead in size. It also adds no
> overhead at runtime if you want to make use of it.


I do believe we've finally synced up... thank you Mathias for your
patient and lucid explanation.

On the one hand, the potential uses of the Reflection<> traits are
more squarely addressed by the introspective preprocessor and usages
it supports, so it seems an almost perverse thing having got all that
metadata into an STL-ish container that you can query with the
simplicity and freedom of normal C++ code just to use the freedom to
re-encode it all in templates :-). Remember the preprocessor's run-
time is still the application's compile time, so there is no runtime
cost to using the preprocessor's declaration tree as the basis of code
generation.

On the other hand, the existing familiarity of traits to C++
programmers is unarguable, and the C++ compiler proper has some smarts
built in that would be tedious to emulate, and may simplify things for
the end-user/developer. I think a point you made (I've quoted it out
of order), makes a good argument along these lines...

> Making the information compile-time allows it to be much more useful
> since the compiler is aware of the typing system.


I'm sold: thank you for the suggestion.

But I'm sold on the idea of generating traits, rather than sold on not
adding the functions I suggested. What's discussed above is all a
layer below the intended usage of the functions you queried. Those
are only intended to address those cases where you'd also end up doing
the "copy parts of it" that you mention below...

> If the information is needed at runtime, you're free to copy parts of
> it.


Writing the code for the introspective preprocessor (frustrating
verbose to keep calling it that, but the name might change before
release) to generate traits code, then more code to support run-time
queries based on the traits, would be very much the long way around.
When supporting run-time usage, the results from the approach you're
suggesting are bounded to at best equal what the preprocessor could
generate, but as the preprocessor isn't restricted to what's
convenient when querying templates, and can generate perfect-hash
tables / sorted static containers etc on the fly, it may actually do a
little better.

> The code before is just an example.
> Member variables would expose a functor that takes an object and
> returns the member. Static variables would expose a nullary functor
> that takes nothing and returns the static variable. Of course, the
> functors would expose the returned type, i.e. the type of the member.
> Member and static (member) functions are more complicated, though,
> since there can be multiple overloads, templates, etc. A solution
> would be to expose simple functors that behaves exactly like the
> combination of all overloads, and expose those overloads with the
> result_of protocol. It however doesn't really expose the various
> signatures. You may think of a way to mangle a signature using
> metaprogramming so that more advanced uses can be made.


A wealth of insight and experience there... thanks!

All up, this is an interesting divide: the preprocessor can support
all the body of template hackery and magic that's already a rich
repository of programmer's work, linking up loose ends and filling in
the bits that were being done manually, scaling and maintaining
techniques that are otherwise error prone or prohibitively tedious.
Alternatively, it can be used to allow even programmers unfamiliar
with all that to do powerful introspective-based tasks in a style like
high-level OO application development. Best tool for the job and all
that.

Really, thank you very much for your time. Made for an interesting
and stimulating couple hours.

Best regards,

Tony

P.S. At some transient moment during the drafting of my response I
ended up reacting to your mention of "bloat" by writing an explanation
on the general issues around controlling the scope of automated code
generation. Now, it seems tangential to our discussion re these
functions, but since it's written, thought I'd put it somewhere for
anyone with a strong stomach for tedious detail... not suggesting you
or anyone read it unless you're bored and want to be more so :-).

"Taking a more general look at potential executable bloat: when the
introspective preprocessor is processing an inline code-generation
instruction, a common requirement is knowledge of the scope within the
declaration tree to work on. Sometimes this will be the scope in
which the instruction appears. Sometimes that scope and all enclosed
scopes. Sometimes global. Sometimes using some manner of search, and
possibly consulting the per-node multimap of attributes/properties for
developer-specified explicit guidance. When writing instructions you
can hardcode any of these, or accept an argument from the in-line
invocation.

So, the functions I mentioned need not be generated in every scope in
an entire program. One can be selective in order to control
overheads.

Still, another way of reducing the change of generating run-time
access functions for scopes in which the compiler can tell they'll
never be used is to make the generated functions I advocated
templates. Maybe not always ideal, but perhaps workable, especially
as both using the preprocessor to control the scope of generation and
the compiler to perform only-on-use instantiation might be freely and
usefully combined in many cases.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #10  
Old 09-06-2008, 04:28 PM
Tony Delroy
Guest
 
Default Re: Please suggest use-cases for introspective code generation

On Sep 7, 1:29 am, Mathieu Mazerolle <mathieu.mazero...@gmail.com>
wrote:
> On Sep 5, 2:34 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
>
> > On Sep 4, 11:23 pm, Tony Delroy <tony_in_da...@yahoo.co.uk> wrote:
> > IMHO, there is no such thing as auto-generation of any type of
> > serialization. C++ (and pseudo-C++) programmers the world over have
> > been trying in vain to add introspection to C++ with no success. The
> > reason is that it is not possible. Computers cannot read. A thinking
> > being (person) will always need to indicate whether variable should be
> > serialized or not, and once that indication becomes necessary all bets
> > are off - the brain energy would have just as well been spent in
> > writing the serialization code.

>
> Introspection is very useful, and has applications such as binding C++
> to scripting languages, marshalling objects for RPC, and debugging. In
> fact, if your compiler did not generate introspective information about
> your program, your debugger would not be very useful.
>
> It should be a simple matter to define a standard way of inspecting the
> static object model and type system of a C++ program. Why has this not
> been done yet?


It is. It has. I had a prototype 4 years ago with serialisation and
a few other basic applications working but didn't pursue it then
because it seemed so blindingly obvious and easy that I was sure some
mega-company would be coming out with their big-corporate-backed tool
any day thereafter, and the code I'd wasn't mine. It was fast too...
ripped through all the masses of STL headers accurately and in a
fraction of a second, so I'm not interested in going the whole hog and
learning how to do it all within GCC or something when it can be done
cleanly and in a compiler-independent way. Some people probably make
the problem much harder than it has to be. Years on and I'm wondering
why I'm working 8-7:30 for a bank 5 days a week, and figure this is as
good a bet as any for changing that, reimplementing everything from
scratch with the benefit of 4 extra years' experience and I like the
way it's shaping up, though doing it in spare time is harder than full-
time.

As for others, perhaps they've been held back by Le Chaud pronouncing
it impossible... ;-P.

Tony


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 09:06 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.