Why Another Component Technology (WhACT)
I'll tell you why, because the ones we have to date (Spring 2002) stink!
Let's define some terms before this rant gets started.
- Is a collection of code (compiled, if possible) contained in a single file.
- Allows applications and other components to instantiate objects whose methods are implemented in the component.
- Clients of a component access objects instantiated from the component through interfaces.
Least Common Denominator Types (LCD Types)
- allows you to integrate Components written in different languages
- allows Components on different machines to communicate over a network
- a set of data types which are compatible with all programming languages being used
Ok, so these definitions stink. ComponentDefinition
has much better ones.
On with the rant...
What's wrong with current Component Technologies?
- Some have limited language bindings to integrate components written in other languages
- They integrate poorly with C and C++ But: ItsTimeToDumpCeeSyntax
- They force a Component to communicate with LCD Types in order to be accessible from arbitrary client languages
- They aren't open
- They change too slowly for today's language explosion
Point number two deserves some explanation. I come from a C/C++ background. I don't have a large range of experience with Component Technologies, but I've read articles and sample code for the ones I haven't used. My main experience is with Microsoft's COM and DCOM.
, etc., then No it ain't easy.
I've gotten in the habit of separating components into two separate projects: the inner problem domain is a static link library, and the outer COM-aware part is a COM server that links in the inner part. This allows me to keep the problem domain code free from all the COM gumbo. The COM-aware part contains conversions between the COM multilanguage compatible types and pure C++ types.
While this arrangement works, it is way too much work.
So, you ask why should a Component Technology cater to the C/C++ crowd? Why should it make the C/C++ programmer's life easy?
Because a Component Technology should cater to the programming languages on top of which everything
runs. You will always
have C/C++ code sitting under every Visual Basic, C#, Java, Perl, Python,... application. The operating system, language interpreter, virtual machine, drivers, yada, yada are all written in C and C++. While many languages do provide the ability to integrate C, and sometimes C++ code into a language, it is through an API specific to the host language. This requires the C/C++ code to conform to the restricted data types and language constructs of the backdoor API. Since these backdoor APIs cater to C/C++ only, they don't count as a Component Technology.
If C and C++ are always going to be present on a system, then why the @$&*#@ don't they make Component Technologies that cater to those languages?
There are loads of code written in C. Absolutely tons of it. To make this code available using COM (ComponentObjectModel
), CORBA (CommonObjectRequestBrokerArchitecture
, UNO, DotNet
, etc. would be excruciatingly difficult.
Equally important, the C++ language provides some astoundingly powerful libraries, which are crippled when you try build components with C++. As an example, consider the following trivial function:
void SortFloats?( std::vector<float> & vec )
std::sort( vec.begin(), vec.end() );
If you have a good optimizing compiler and a good library implementation, this sorting routine will be extremely efficient. Now that you have this function written, how do you expose it to applications written in other languages? How do you avoid the overhead of converting all the function parameters to Least Common Denominator (LCD) data types?
Here is what I want in the new Component Technology (WhACT):
- The ability to expose functions like SortFloats?(), with _no_ extra coding effort, as component methods
- The ability to pass data between components without resorting to LCD types
- The ability to pass data between components written in the same language without incurring any unnecessary copying and conversion
- no corporate (MS, SUN) control over the technology
- no standards committee (ISO/ANSI/ECMA) control over the technology
- no other committee (OMG) control over the technology
I don't know how to satisfy all these requirements, but here are a few ideas to get the ball rolling...
Caller Callee Bridges
When code in one component makes a call on an object in another component, the system should identify which languages the Caller and Callee are implemented in. Based on the languages involved, a specific conversion Bridge should be selected, and used to translate the in and out parameters for the method call.
If the Caller is written in C, and the Callee is also written in C, then passing an array of int's between them should involve no conversions.
If the Caller is written in C++, and the Callee is written in Java, then passing an unsigned short into the Callee will require a conversion because Java does not support unsigned types.
The Bridges between different languages will require widening and narrowing of data types as needed.
Since WhACT won't be controlled by any one group, anyone can put together their own Bridge, or set of Bridges. If you don't like Joe Smoe's C#-to-Perl Bridge, then use someone else's. Since many of the emerging languages are designed, distributed, and implemented as Open Source projects, I hope that building a new Bridge should be a matter of tweaking an existing Open Source Bridge.
So, how do you get this seamless language integration? In C++ you could do some tricks with templates to do some of the work. In C you don't have type deduction facilities like in C++, so what do you do?
Code generators, code wizards, and language preprocessors all might provide the extra layer of code required to tack-on the Component Technology smarts to C/C++ code.
For other languages you might be able to use runtime type information, like Java's Introspection or Microsoft's IDispatch.
Another strategy for languages with C/C++ backdoor APIs is to use these APIs as the attachment point for Bridges.
Why Shouldn't A Committee/Company Control This?
The controlled Component Technologies available today all have issues related to the control itself. Sun has loosened its grip on Java to allow some steering by outside entities, but only to the degree that it benefits Sun. Making Java Beans play nice with .NET would benefit developers, but Sun will probably block every effort in that direction, as they did with COM.
Likewise, parts of .NET have been standardized by ECMA, but only the parts Microsoft wants to standardize.
CORBA is maturing, but jeez, could you guys be any slower? While the CORBA committee process seems to be open, it takes sooo long to get changes made.
So, you've got pseudo-vendor lock Java Beans, DotNet
, etc. or you have design-by-committee with CORBA. Meanwhile, new languages are popping out of the woodwork. Integrating all these newbies with the existing Component Technologies will either never happen, or it will take freaking forever.
If I want to call a Ruby component from Java, I should be able to do it now
, or at least build the needed Bridge now. The development of new languages has really opened up, unfortunately picking one language to build your whole system with is not realistic. Different languages are better for solving different problems. We need Component Technologies to tie together code written in these different languages.
We need Component Technologies to solve today's problems today. We need to open up the Component Technology field so developers of new languages can build Bridges at their own pace. Developers in SlickLanguage?
++# should be confident their code will integrate with existing systems written in other languages. If it takes 5 years to get such integration, or a dispensation from some corporate Pope, SlickLanguage?
++# will be dead by the time the integration arrives.
PHP-to-VB.NET anyone? How about UnixShell
Language-neutral object model?
C++ provides parameterized types and multiple inheritance of implementation, while Java does not. Java uses garbage collection, while C++ does not. Eiffel encourages rich contractual expressions that both C++ and Java lack. Eiffel's genericity differs from the genericity of C++. Java's method parameters are statically typesafe, Smalltalk's are not.
Different languages provide different object models. In my opinion, the idea of language-neutral components based upon semantic interactions with language-level objects is nonsense. If you try to force languages into a uniform semantic model, you limit those languages such that their differences become inconsequential syntactic differences.
Aside from the occasional pragmatic need retain legacy code, any legitimate rationale for using multiple languages in a single system must be based on the fact that one language offers a more appropriate semantic match to part of the design than another language.
In my opinion, any attempt to integrate languages at the object level will yield a bad fit on both sides. I think a far more realistic means of integrating multiple languages is through (probably non-OO) service
abstractions. That way, you can use the unique expressive power of each language according to its own distinct programming model and design style.
-- and this was written by....?
Rather than force all languages to conform to some common set of object semantics and LCD data types, WhACT should not require "complete" Bridges between languages. For passing Simple Objects
like numbers and strings, you should be able to build Bridges between most languages. Passing Arrays of Simple Objects
likewise should be possible with some translation between array representations in the two languages. Passing Common Containers
like maps/dictionaries/hash tables of Simple Objects
should be possible between most languages, but not all.
When it comes to passing around User Defined Objects
you run into some serious issues. On that we agree. I don't know how you would pass a User Defined Object
in C++ to Perl. Or for that matter, if you were using a C++ object in your Perl code, how would you pass it from Perl to Scheme?
Maybe the above author is right, maybe a better angle is non-OO. Maybe the inter-language communication should look more like libraries that expose procedural APIs.
I invented a few terms here to clarify my original thinking on data types. I realize the Simple Object
, Arrays of Simple Objects
, Common Containers
, and User Defined Objects
definitions are hand waving. Some languages treat everything as an Object
, while others treat some data types as values and others as Objects
. Drawing a line between these categories would be difficult. I suppose different Bridge implementers could decide for themselves how wide to make the Bridge. Some might only allow Simple Object
Maybe these are intractable problems. Solutions anyone?
Someone inserted a link to ItsTimeToDumpCeeSyntax
earlier in this page. I actually agree that most software should not be written in a lower-level language like C, or for that matter, C++. Programmers need the ability to choose which language to use for each part of an application. Use C++ for the performance-critical, bit twiddling parts. Use a RAD tool for GUI development. Use a scripting language for other parts, etc. If we want the freedom to select the appropriate language to solve a problem, we need a way of easily integrating code written in these different languages.
's common type system provides some hope of solving some of these problems. A COM component can be treated as a .NET class, and can be inherited/overridden by classes written in whatever programming language you choose. It may just be another complicated layer on top, but at least it does make "components" accessible from multiple languages.
Use an XML (or whatever) intermediate message format, most objects can be serialized as strings or numerics. This isn't a hard problem until you try to make the bridge generic, then you are straight into CORBA land, trying to be all things to all people.
Automated bridge-builders for exposing C++ to other languages: