Hi Josh, > References and containers can do the trick as well. For instance, take > the following scenario: > > You create some sort of sorted container that holds > complex objects by value. You lookup one of those objects > and you want to do a number of operations involving one of > its subparts. For efficiency, get a reference to that > sub-part, so you don't need to keep asking for it or > make an extra copy. Then, in a moment of blindness, > some result causes you to insert a new item in > the container. You may very well now have an > invalid reference. I don't intend to argue pedantics, but there are no sorted containers that allow mutable access to its member elements: set<Ty>::iterator is a synonym for set<Ty>::const_iterator. Even so, I take your point -- if you modify a container whilst you are traversing it, you are asking for trouble. Yes, I've done this before and yes it is difficult to find the problem. Using smart pointers helps. So does simply not mutating a container that you are iterating over. If banging your head against a wall hurts, my best advice is to stop banging your head against the wall. > Even an "expert" can make such mistakes from time to time > when they are not paying attention and spend a while tracking > them down. True enough. But an 'expert' is simply someone who has made /more/ mistakes, or at least learns from them quickly. > >[skip rant about access to a parser that can be supplied as a library, or by > >using ANTLR] > > Recalling the existence of parser generator tools is a long way from > defining and implemented an interpreted lanaguage, especially one with a syntax > as complex as C++ and an as yet not fully specified semantics. > I take this flippancy as a sure sign that you have never attempted > any such thing. Um, or from the simple experience of writing a number of game scripting languages over the past few years. I have written a Java-like interpreter, and a number of other C++-like languages, all using standard C++ with libararies. The most joyful experiences with interpreters I have had have come after I found ANTLR. No, ANTLR doesn't do everything for you. It doesn't give you an object model, a marshalling system, or an execution model. But it certainly renders the job viable within a few days/weeks/months. I wrote a scripting language (pi) for our game -- a complete prototype took two weeks. It had a hierarchical object namespace (not the rummage sale that is the C++ heap), and provided a UNIX filesystem-like interface to the (interactive) interpreter. Name resolution and inheretance was implicit in the name of an object (that is, where it resides in the object tree). Point being that I understand the difference between a LL(k) parser generator and a scripting system. > >e) You don't need to 'write a wrapper for calling compiled code'. You just > >call it. > > Are you really familiar with Managed C++? I'm not, but Microsoft seems > to have a different ideas about it than you do: > > http://msdn.microsoft.com/vstudio/nextgen/technology/managedext.asp Just because they mention the word 'wrapper' in the context of MC++ means little. [..] use managed extensions to write thin, high-performance wrappers that make your C++ code callable from .NET components. and The wrapper class acts as a mapping layer between the managed class and the unmanaged C++ class. Fairynuff. All this says is that you must use a .NET CLR language in there somewhere if you wish to use .NET CLR. If you are staying within the CLR howerver (for instance, calling MC++ from Python, or building a VisualBasic class hierarchy using a mixture of MC++ and Perl classes), then you do not need to 'wrap' anything. From Python, if you want to call a method defined in VisualBasic, you just call it. From REXX, if you want to create an object that is defined in MC++, you just do so. No wrapping required. > I know quite a bit about templates and template 'meta-programming'. > That's why I mentioned templates in response to your original claim > that C++ provides good support for metaprogramming. It doesn't. > > The book _Generative Programming: Methods, Tools, and Applications_ > by Czarnecki and and Eisenecker has some especially amusing chapters > on the theoretical Turing completeness template meta-programs. Sorry, I had some trouble understanding the end of this sentence. > But from a practical point of view, these techniques are mostly > amusing tricks. You obviously haven't used meta-programming techniques practically then. They don't address most of the real world > meta-problems that a programmer might face and they don't > transcend the need to be able to define the executable > routines of interest at compile time, before interacting > with the user and their specific input and data. Um, what is a 'meta-problem'? Surely there are just problems. Maybe we are talking about different things. By "meta-programming" I mean a set of techniques that allow the programmer to define and build-up types and type systems programmatically. What you describe sounds like choosing a DLL to load. That isn't called "meta-programming", that's called "loading a DLL". I have also heard the term 'meta-programming' used in a different context, namely the study of program structure and some parsing systems. But when I refer to "meta-programming", I am explicitly refering to the former definition. For instance I find the following types as important as anything else in my toolbox: template <int Test, typename A, typename B> struct IF { typedef A Result; } template <typename A, typename B> struct IF<0, A, B> { typedef B Result; } template <class Ty> struct is_void { enum { Result = false; } }; template <> struct is_void<void> { enum { Result = true; } }; template <class Ty> struct Storage { typedef IF<is_void<Ty>::Result, char, Ty>::Result StorageType; private: StorageType storage; }; Storage<void> foo; Storage<string> bar; Other important 'meta' techniques that I use daily are meta-lists (programatic building of and traversal of lists of types), and property systems (extracting values and referencecs from objects based on tags). The code in my property system uses techniques best described as mutual recursion in the meta-program domain. I'd elaborate but it get's very sophisticated. I will do so if you are interested. > ordinary function object technique is a big improvement > on C, in this regard, but still quite limited compared > to the techniques offered by an interpreted language > with closures, etc. Many meta techniques are meaningless outside of a strong statically typed system. Or perhaps that is true only as far as my understanding of meta programming. Perhaps you could give some examples of meta programming in Ruby or another interpreted language? Post script. Perhaps you mean generating program source code from a program? That would qualify as 'meta-programming' as well, although it would seem a less elegant solution (if only because it requires two stages). > -= Josh Christian.