
The goal I have/desire is to preform type transformations and allow the programmer to specify these transformations in a generic way
From what you say below, though, it seems that there may be some differences in design or focus. You seem to focus on what happens during an assignment, and want a single assignment to be reflected in
That is more or less the same goal as I have for the Domain library. the value of potentially a number of other variables.
Yes that is what I want. This is what I mean by data binding. A bunch of values can be bound together so that when one changes they all change instead of having set a value to call each conversion function in a chain.
In contrast, I am thinking of what happens when other functions (including but not limited to operators) are called. The idea was to allow the user of the Domain library (I envision this person most likely being a developer of another domain-specific library) to craft the set of type tags, conversion functions, and functions/operators, and then have an idiomatic MPL-based means of specifying how they all go together. The job of the Domain library would be to invoke the MPL code for domain selection, etc. so that the user of the library would not have to worry about this and even more so, so that the user of that library would never have to worry about domain transformations when they call the functions/operators but could rely on domain correctness, even in completely generic algorithms.
Users of the libraries often become the extenders of the library when ultimately it does not meet there needs. All libs suffer from this. So making it extensible is important to allow the user to extend it to their domain. This library is then a library for library developers for domain specific transformations?
I will give more thought to rolling the assignment operator into this, but I'm not sure yet how the two ideas fit together.
Give the demo code a try if you haven't... Either you will be aghast by what I have done or find it a very nifty bit of code. I guess there will be very little middle ground for those who see how it works.
Yes so some types can not be automatically transformed. My example provides absolutely no support for this except for 1 to 1 translation... for disparate types it is... well... compiler errors waiting to happen if no translation functions are supplied.
You mention the possibility of a 1:1 transformation. In my context, I'm not certain what that means. To me that signifies two different types in the same domain. Those can only be differentiated with respect to their value types (i.e., the types actually holding the data as opposed to the parts that track the domain information). In my scheme, as long as one value type can be constructed from another, there is always such a transformation within the same domain. No need for special support. Did you have something else in mind?
What I mean by 1 to 1 is that if no transformation functions are specified a values A set and bound to value B will be equal 1:1. If you set A to 1 B will be 1 if you set B to 45 A will be 45. What I mean by compiler errors waiting to happen is that there is not type checking for primitive types (it is as was only a simple example of what I had in mind.) so if you pass in T1 = float and a class for T2 without transformation functions you will get compiler warnings when you set A to 2.34 ... what does the class B equal? ... compiler errors.
It will always be the case that certain operations make no sense for certain domains. Thus, it is possible to try to use expressions on the generic domain types that cannot be resolved by the appropriate template specializations. I see this as no different from trying to use any ill-defined expression, though. The compiler will catch it, you will pay more attention to the documentation that describes what is legal for that domain, and you will fix your code. What else is possible?
That seems perfectly reasonable and correct.
The software engineer shall be allowed to specify a transform is the compiler cannot automatically figure it out.
More precisely, the engineer must specify a transformation between domains that must be interconverted. Except for the trivial case of transforming between value types within a domain, which is really not a domain transformation at all, the compiler cannot possibly know what transformation is appropriate.
The goal here is to make it easier for an engineer to construct a library appropriate to a particular set of domains (an application domain if you will) so that the users of his/her library in turn have a truly easy set of generic, but domain-aware, operations to work with.
How difficult is it to specify new types and tranforms.... Are we talking about the types like thoes defined by the section titled "A Deeper Look at Meatafunctions - 3.1 Dimensional Analysis" in "C++ Template Metaprogramming" by David and Aleksey? If so ... ouch... could be quite painful to specify new types and conversions... What is your approach?
Developing a domain-aware library based upon the Domain library essentially involves the following:
- Naming the set of domains and the individual domains within the set. This is only a matter of creating a set of tags for dispatching; essentially this is an organized set of empty structures to create convenient names that guide template specialization.
- Potentially, creating an appropriate set of value types to hold whatever information is needed. In many cases, these will be preexisting types; in others, they will need special construction. As always, it all depends on the application domain.
- Creating the domain transformation functions. These are a set of specializations of template functions within a defined namespace.
- Potentially creating any appropriate definitions for operators. These are a set of specializations of classes within a defined namespace.
- Potentially creating non-operator functions on the domain types. Since these cannot be known in advance (unlike the operators), a bit more work is required on the part of the user of the Domain library. However, this is largely idiomatic and easily supported within the framework.
- Identifying which domain transformations are available. This involves a specialization of a single class within a defined namespace.
- Identifying which domains are appropriate for which operations. For example, additive operations may be defined for all domains, but multiplicative ones defined only for some. This is handled by a set of simple MPL vectors of domains. The library takes care of sorting through the domains of function arguments, the set of domain interconversions, and the domains that are appropriate for the called operation to find an appropriate domain. The arguments are converted to the target domain if necessary before the operation is performed. This is perhaps the main thing that makes the library useful, as this makes the operations generic while maintaining domain-correctness.
Yes sounds great with the exception of the "operators portion"... like every one in boost using operators for new purposes (think Spirit - and I don't mean this in a bad way) we are running out of operators which provide meaningful schematics...
I am thinking of cases in which the operators already have a natural meaning in the application domain being modeled by all the domain types, but that the implementations might differ among domain types and so interconversions are required. This is quite different than overloading operators to describe an entirely new language, as Spirit does.
Let me just clarify what I mean here. Consider Matrix calculations where it would be nice to be able to use operators standard to the domain where you have X = { 1 } { 2 } { 3 | As a column vector It would be great to type in c++ X' and get {1 2 3 } the row vector, but alas we cannot type this in C++, but we might be able to if we had access to other operators which look like this because we would be writing code in a Unicode editor with a complier that supports Unicode text and has been expanded to utilize the new operators that using such a coding scheme would provide. I would not see backward compatibility issues here as if you are using a Unicode Editor you are writing forward compatible code. Have you ever been writing code only to find that you wish the syntax you desire was possible, but you are limited by the limited set of operators by which to overload. They can speak to it, but I am sure the Spirit and Karma guys might agree with me here. This however is a off topic for this and a little too forward thinking. Sadly I feel we have been crippled as developers by standards based on UTF8 encoding :-( Lets free our compilers and free our code... Unicode ... Who's with me! ... I'll digress again...
What happens when and operation cannot be found in a domain, but the programmer can or needs to specify one? Is it extensible?
Yes, generally by specializing things in well-known namespaces.
The easier it is to provide new specifications for types and their transformations the better.... you'll never think of every domain and translation. Need to supply a clear path to adding new types, domains, and translations.
Of course. The goal is to make it easy and idiomatic for others to do this, not to anticipate all possible uses. As I mentioned, the role of this is as a base layer upon which application domain-specific libraries are easy to build.
How do I obtain the code and where is the problem?
I'll try to get it in shape for public consumption this weekend. I have a worked example based on a toy polynomial library to illustrate how to build a library on top of the Domain library. However, the documentation is mainly in the form of Doxygen comments and so I need to give a bit more of the overview. Stay tuned. ...
I am familiar with running Doxygen and bjam. Can't say I am an expert in either, but I can find my way around with these tools. I am interested to see what you've got. It sounds like you have given this a considerable amount more thought that I.
Gerneric domain is exactly what I am after. We have type T1, T2, T3,....TN and we have to translate between them... What's the easiest way to specify this for the programmer?
That and how to automate the process of choosing the transformations is what I'm trying to make easy. As soon as I can get the code out there, please let me know how to improve the ideas.
Thanks alot for your interest so far. I look forward to additional comments.
Out of curiosity do you think this library could support time domain transforms to Z-transforms and S-transforms. How complex a transformation do you think it will support? I help where I can. Provide input where I can and hope it helps. Brian