There, I said it.
I hope, finally, we can start to put the old Dynamic vs Static language schizm issue to bed. C# now is a dynamic language. Rubyists eat your heart out (and I mean that in good fun).
Lets go down the line – things that make a language dynamic:
‘Eval’, or more generally, ability to construct a data structure and compile it all at runtime.
All this is possible within the Expression namespace. While I can plug my own MetaLinq with it’s ExpressionBuilder as a way to more intuitivley build an expression versus using the factory methods to do it, either way, it is clearly possible to have "Eval" style functionality within C#. In C#, as you can in Lisp, you can write programs that write programs. And with 3.0, you don’t even have to deal with Reflection.Emit to do so.
Higher Order Functions
Lambda Expressions are part of C# 3.0 – part of what makes a where clause in LINQ able to work. The syntax is actually pretty reasonable as well.
Gone is the requirement that you put put a formal type on everything you use. Now, it is a good idea that they keep that requirement for public references – things that will escape the comfortable confines of your assembly – but within that, being able to use the var keyword, especially as it relates to programs where the shape of the objects are expected to change a lot, is a good thing, contributing to the dynamicness of the language.
Anyone that has implemented an enumerator in C# 2.x knows that we have had continuations (via the yield return statement) for some time, though I do not see them used a lot in practice. Don "COM Is Love" Box has a great post on this from 2005 talking about the concept.
Leaving aside the reflection namespace, the fact that you can cast Lambdas to expression trees in C# 3.0 – the whole basis for what makes something like i4o possible – is demonstrating that introspection is a huge part of the new innovative stuff coming out in C#-land.
Now, it does not mean C# is dynamically typed – which is different than being a dynamic language. There is a great whitepaper from Erik Meijer and Peter Drayton about the subtle differences there. However, what I am saying is that the lines are almost certainly blurring when talking about the differences between static and dynamic languages.
Of course, if we really wanted dynamic typing, we could have forgotten all this semicolon nonsense and just switched to VB 5 :)