C# 3.0

Pretty early on in the development of the neptune language we noticed that if you want syntax coloring when editing neptune source in editors that didn’t know about the language, a syntax coloring mode for C# is usually the closest approximation. That may not be a coincidence: I don’t actually know C# very well, I don’t think anyone in our group do, but for some reason neptune has drifted in C#’s direction.

Amazingly, the C# also seems to be drifting towards neptune: the new C# 3.0 spec describes the new constructs in C# 3.0 and a few of them are very similar to constructs in neptune.

One new construct in C# 3.0 is implicitly typed local variables. For instance, you can write

var i = 5;
var s = "Hello";

and the compiler will infer the variable types for you from the initializer and understand the code above as if you had written

int i = 5;
string s = "Hello";

In neptune you can also declare variables without specifying the type, using the exact same syntax:

var i = 5;
var s = "Hello";

In neptune, however, the type is not inferred but left undefined — neptune has optional typing and you are always free to leave out the types. So where this is illegal in C#:

var x = 5;
x = "Hello";

since x is inferred to be an integer, it is perfectly legal in neptune. You are also free to leave out the initializer in neptune, since we don’t need it to infer the type as they do in C#. So the constructs are a little different when you look closely but still pretty similar.

Another new construct in C# 3.0 is collection initializers. You can now write

new List<int> { 1, 2, 3, 4, 5 }

which gives creates a new list containing the five specified numbers. In neptune you can do exactly the same (except that we don’t have generic types) and, again, with exactly the same syntax:

new Vector { 1, 2, 3, 4, 5 }

Not only do the two constructs have the same syntax, the coding convention used in the spec is the exact same as I use in my code: a space after the class name, before the first element and after the last.

There is a subtle difference in what the code means in C# and neptune, but it makes almost no difference in how the constructs works, only how efficiently it can be implemented. In C# the expression above is implemented by adding the elements to the list:

List<int> list = new List();

In neptune collections have a special collection constructor and the elements are given to the collection constructor in a special “primitive” collection:

var raw_elements = #{1, 2, 3, 4, 5} // "magic" primitive collection

Our model has the advantage that we can optimize the allocation of the primitive collections which can often be pre-allocated and, if necessary, placed in ROM on small devices. It also means that collections are given all the elements at once and are hence free to implement new{} in smart ways. In C#, new List<int> { 1, 2, ..., 1000 } must be implemented using 1000 .Adds, whereas new Vector { 1, 2, ..., 1000 } in neptune can be implemented extremely efficiently no matter how many elements are added. (How? By using the primitive collection as a backing store and using copy-on-write if the vector is modified. And you can be much smarter than that if performance is an issue).

Unlike C#, this syntax can also be used to initialize mappings in neptune:

new TreeMap { 1 -> "one", 2 -> "two" }

On the other hand, C# allows this syntax to be used to initialize arbitrary objects:

new Point { X = 12, Y = 16 }

Considering that we knew nothing of these constructs in C# and the C# people of course didn’t know what we were doing (the spec came out before we even started working on neptune) it’s interesting how alike they are. I’m optimistic take it as a sign that maybe we’ve hit a design that will feel natural for people used to C-like languages.

For the technically minded, Ted Neward writes about the gory details of the new C# features. For an overview of all the new features a good place to look is the Code Post.

One Response to C# 3.0

Leave a Reply

Your email address will not be published. Required fields are marked *