In the generative model, instead of a fixed language, I think it is better to view the system as an extendable language framework. The base language allows new language elements to be added to new "dialects". It handles the selection of the right dialect to keep extensions from conflicting but allows code to use constructs from potentially incompatible dialects. Overtime, dialects can be merged into their base dialect to allow for the evolution of the system.
Dialects can also be used to restrict features from simplified versions of the language. This can be used to create "simple" versions of the language which use only basic constructs in the language. I think this is a better alternative to solving problems which are currently solved with XML. Instead of defining a new language for each XML file format, you define a restricted set of constructs which you can store in this particular file. The end result is a file which can be edited by a person who only understands a piece of the much larger system. We can have a single smaller family of "cooperating dialects" in a single language. There are evolutionary rules that in the long run allow you to combine and coalesce languages into one.
The generative programming model has many advantages for developers. It allows for more performance optimization tradeoffs during the generation process. It might for example generate a slower version of any given module during development which has lots of validation and testing logic enabled. The version of the code which is changing rapidly can be "loosely linked" with dependent code so that the turn around time is faster. As the code gets tested and more "fixed" a more optimized version which removes these checks and optimizes "fixed" relationships can be generated. We can generate both safe versions of the application which are robust to code errors or a faster version which assumes that the code has been debugged.
It gives us back the ability to execute code at compile time, but in a more natural way than the clumsy and bloated C++ Template model. It gives domain specific languages the ability to add new language features to a full fledged base language. The one rule is that new language features cannot invalidate any tests implemented for the existing language. This rule can be enforced by ensuring dialects always comply with their comprehensive validation tests.
All in all, a generative programming language which is designed with "evolvability" concerns in mind can serve as a base for a much more flexible programming platform and serves as the base for a lot of what I describe here.
We are starting to see this pattern emerge as lots of vendors are producing such "data integration frameworks". This is the right trend, but unfortunately I have not yet found a framework which has a rich enough data model to "solve" the persistence interface problem generally. Until we have such a model, we'll have lots of competing persistence frameworks. In my view, the lack of integration on a single consistent persistence framework is the biggest remaining inhibitor for improving the reusability and efficiency of software.
In other writing on this site, I talk about some of these features in more detail but a persistence framework needs rich models of transactions with a variety of policies for conflict avoidance/resolution, lifecycle/scope, queries/indexing, integration across disconnected sources, constraints, caching/timestamps/invalidation events for scalable data access, and versioning with collaboration facilities and longer-term conflict resolution features. This is clearly a huge project to design and implement such a system and that is probably the reason we have yet to standardize on any one set of interfaces for persistance across the industry. For huge projects, you typically need a huge company but saddly all of the huge companies are strongly positioned against the creation of such a simple and universally useful piece of software. How would Oracle sell its database for $$$ if customers had the ability to switch their databases as allowed by this type of system? IBM, Microsoft and other big companies typically have many groups in their development organizations which are strongly tied to existing persistence interfaces and actively reject any standards proposals that lean in on their turf. They will not accept a standard which covers their turf with a tarp until they are forced to by its acceptance in the industry.
Since I've worked on pretty much all of these features in various capacities for ATG, I do believe I understand how to design and build these persistence interfaces. Once the interfaces are designed, the implementations can be added incrementally. I think since this system is a generator, it can generate code to interface into existing platform code. That said, it is still a big project, but I'm still feeling young :)
It is also important to be able to allow code to depend on interfaces and to have implementations compete for the ability to implement a specific "new" of a given interface. For example, it should be easy to change the implementation of hashtable in a given package, file, etc. from one which optimizes time to one which optimizes memory. Right now, that requires access to the original code or specialized coding by the developer for this common type of change.
One big problem is that the resulting combined languages tend to be much larger and more complicated. The syntax and mechanisms of functional programming are intuitive to mathematicians and other geeks who think that way but opaque to most people making these languages even harder to learn than purely imperative languages like Java. It is easy to write "write-only" code.
But functional constructs still have the potential to improve the programming process even for regular programmers. The basic point of functional programming is to define the logic for any computation using a mathematical style formula without any side effects. Imperative code always depends on state and time whereas functional constructs define rules which are always true. With functional code, the computation may be expressed simply and elegantly in a form which makes it easy to prove the results. The actual execution of the formula can occur in a variety of ways - lazy or aggressive or some combination of the two as the implementation sees fit.
In general, when you do not have to worry about lifecycle, memory allocation, flow of control and timing your programming process is a much simpler one. But of course, writing any complex set of logic in a purely functional style may be difficult or impossible and performance of the resulting applications may not be competitive with the imperative equivalent. There is often no tuning how the computation is performed in functional languages.
My belief is that if functional concepts are well suited for defining application "rules" which are either invariant or based on certain well defined application states. By keeping these constructs simple, they can create a higher level of abstraction for expressing rules, relationships, constraints, queries etc. Business rules for example might be expressed solely as these functional constructs which a user could edit directly with the appropriate wizards. Assertions and data integrity constraints can detect errors more quickly and are functional in nature. When you express program logic using functional constructs where they are suitable, the implementation of the system closely matches its design. I believe this will be a more efficient system.
But what about performance? In the generative model, these rules can be compiled into efficient implementations. Also, the techniques used for evaluating any given rule can be tweaked with meta-data. This meta-data is parsed at compile time and so can cause functional rules to be tuned where necessary to get the equivalent peformance with a similar imperative implementation.