Tim Jansen's blog


2005/09/18
C# 3.0 features pulled to pieces

Just found out on Slashdot that the details on C# 3.0 are out. This word doc gives a nice overview over C# 3.0's features. I already read about some of its features and was a bit scared because it seemed to contain some features that sounded interesting. But now, after reading it, I realized that I had no reason to worry...
In order to understand the following comments you should have read the C# 3.0 overview.

26.1 Implicitly typed local variables The var keyword is a bit like Eek's any type. However, it is only intended to reduce the amount of characters that you need to write. It does not offer late-binding or any other of any's advantages. Instead it brings some new oddities that will confuse inexperienced programmers (like forbidding to assign null to a var), and increases the language's complexity budget. I would have opted against that feature.

26.2 Extension methods Extension methods are a feature that can be quite tempting: adding methods to a class that you did not write. It does not offer any semantical advantages, but can save you a few keystrokes. Sometimes I'd like to have that feature as well. So I thought a lot about it - and decided against it. There are two reasons against it: first of all, it's another odd syntax to increase the complexity budget and that will confuse newbies, because it is a rarely needed feature. Second, it makes it harder to find a method's implemention. Without extension methods the implementation is easy to find: just look at the class. However, when you can add methods to a class at any place, the methods can be anywhere as well. Only when you look at all imported classes you have a chance of finding the methods implementation. Or, admittedly, with a good IDE. But all this trouble only to make method invocations a bit more convenient? No thanks. (BTW I don't like AOP for similar reasons).

26.3 Lambda expressions Now this is a crazy feature. C# already has anonymous methods. Because the anonymous method syntax is quite verbose, they add a second mechanism? Especially one that's so complicated (because of the type inference and the somewhat odd syntax)? I really wonder why... Eek is much simpler, as descibed here. I have one closure feature that's similar to C#'s anonymous methods, and as a special case anonymous closures .The latter are even more compact than C#'s lambda expressions, but do not allow more than one input argument and one return value. I considered extending the syntax to more input arguments though, it would be possible.

26.4.1 Object initializers Once again a quite complicated and potentially confusing syntax. Eek has them as property initializers, but they belong to the constructor's arguments. To create the class

class Point
        int x, y
end
you'd only have to write
any a = Point(x: 0, y: 1)

26.4.2 Collection initializers That's a feature that does not need any language syntax support in Eek. A constructor with variable argument number length is sufficient. To initialize the list in the C# example, you would have to write

List[int] digits = Init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Init is a initializer class whose constructor takes an unlimited amount of any values as arguments. For optimal performance the compiler should know the Init class and make some optimizations, of course, but there is no need to introduce a new syntax.

26.5 Anonymous types Anonymous types are another strange feature without much use for most use cases, at least without duck-typing. I understand that they are required for the next feature, but they are still another blow for the complexity budget.

26.7 Query expressions The real surprise is the embedded query language. I also played with the idea of including XPath, but decided against it. No query language on the world is worth the complexity that it adds to the language. Obviously the C# designers did not agree - even though their query language does not even offer any new capabilities, but is just syntactic sugar for method invocations with delegate arguments.

Eek has the much simpler filter operator, which can do what C#'s where declaration does. With the following class declarations

class Customer
        String name, city
        List[Order] orders
end

class Order
        Customer customer
        Date date
end
, you could select all customers from London with the method:
getAllLondonCustomers(List[Customer] l): List[Customer]
        return l.{it.city == "London"}
and get all orders from London in the year 2004 with the method
getAllLondonOrdersFrom2004(List[Customer] l): (List[Order] results())
        for Customer c in l.{it.city == "London"}
                results += c.orders.{it.date.year == 2004}
I dont think that this is worse than the C# example:
from c in customers
where c.City == "London"
from o in c.Orders
where o.OrderDate.Year == 2005
select new { c.Name, o.OrderID, o.Total }
The main difference is the result set. The C# example returns an anonymous type which can include elements from all involved classes, which Eek can return only orders. So in order to access the customer name you'd have to write order.customer.name.



 

This blog is my dumping ground for thoughts and ideas about Eek. Someday Eek will be a programming language and system, somewhat comparable to Java in scope. It is my attempt to bring sanity to the world of computing.
At least I hope so. Right now it is far from being finished and I can't guarantee that it ever will be. I am still working on the specification, but I won't release anything before I got my first prototype running. The world does not need more vapourware and unusable beta-software. All publicly available information about Eek is contained in this blog. You can find the latest summary here.
This page is powered by Blogger. Isn't yours? Creative Commons License
This work is licensed under a Creative Commons License.