C# & Data
Anders Hejlsberg, inventor of C#, has repeatedly indicated in several interviews that some sort of database integration would be a major priority in the future evolution of the language. He laments the schism that presently exists between the existing programming languages and the database programming. In the development of Delphi , he noted that database support was essentially an afterthought in the design of the VCL (Delphi’s framework library). Although it was added reluctantly in the second release (or late in the first release?), it turned out to have a major impact in its success of the product.
Integrating database capabilities into the syntax of programming languages is not really new. In the past, database providers often provided a C preprocessor that would extend the syntax of C to provide both a typed and natural inline experience to database programming. I believe this concept is called “Embedded SQL.”
C# 2.0 and Data
In Whidbey, there have been a couple notable steps towards that directions:
1) Nullable types. The Base Class Library includes native support in nullable types in mscorlib with deep integration throughout the framework. In addition, C# 2.0 includes specialized syntax for accessing and performing operations on nullable values natively.
2) System.Transactions namespace. A document by Juval Lowry describes a new namespace in Whidbey to support a high-performance, transactional programming model. In this new model, Whidbey supports either declarative transactions using special attributes placed on a method or explicit transactions using the Using block.
While the declarative support with attributes is very elegant, the explicit transaction could have been made simpler. This is how a transaction block is written in C#.
If a programmer inadvertently fails to call the Complete method (a pretty easy mistake to make with potentially serious consequences as transactions tend to be used in serious code), the transaction is always rolled back. The problem is that when the Dispose method of scope is called, there is no way to know whether an exception had been executed in which case the transaction is rollback or the block completed succeeded.
The System.Transactions actually creates an interface ITransaction that extends IDisposable by declaring an additional Rollback method. So, it would have been possible for create a new Using-like construct in C# that would wrap a block inside a try-catch-finally pattern, in which the catch clause would call Rollback() and a finally clause would call Dispose().
I would like to see some kind of enhancement to the Using block in C# to provide cleaner support for transactions.
Anders mentioned that, for C# 3.0, he and the other designers would do some serious thinking about database programming and are looking at COmega, a current Microsoft research project, for some inspiration. Generics, the biggest investment of the CLR in version 2.0, is actually based off of an earlier research project, called Gyro, which introduced Generics for the Rotor codebase.
C Omega is a very interesting language, though I doubt much of it will actually be incorporated in the C# in the next few releases. C Omega merges two experimental C# extensions: X# or Xen (a new data type extension for XML and table manipulation) and Polyphonic C# (a new control flow extension for asynchronous wide-area concurrency.) It does currently suffer from an atrocious syntax. Some of the concepts in C Omega include
- Bridging XML concepts with C# data structures
- Unification between accesses in memory and within a database using an either (1) XPath-like notation or (2) keywords from SQL
- Support for asynchronous programming
Data In Code
One of the advantages of the LISP language is that merges both code and data. The advantage of this approach is that makes it easier to write and use declarative DSL (domain specific languages) inside the language. Data could be manipulated as data, converted in to code through macros (“meta-programming”), and even executed directly through the normal execution model. Because of the ability to add change the language and create miniature DSLs, LISP programs can be substantially smaller than programs in other languages.
I do see a trend towards direct support for embedded data in C# from Anders’ prior comments. He is looking into borrowing more features from declarative language. He discussed in his last whiteboard “chalk talk” a probable extension to the C# to enable property initialization directly in a new constructor call. This syntax resembles named parameters: For example, Point pt = new Point( X := 1, Y := 1 ). With such a compact syntax, one might actually build an entire object tree in code within one statement, but it still won’t have the versatility of Lisp.