C# 2.0 is just out and Microsoft is already working hard on the next version of C#, version 3.0. In this post, Niek describes a few of the new language features that will be introduced in this version. Please note that the resulting binaries will be backwards compatible with .NET 2.0, so C# 3.0 is only new on the compiler side.
The comments about the var keyword are completely off.
First — there is a distinction between statically typed and strongly typed. In a statically-typed language, the compiler knows the precise type of every variable at every point in the code. In a dynamically typed language, only the runtime knows that. In a strongly typed language, it is impossible to subvert the type system. In a weakly typed one, it is possible to subvert the type system. So C is a weakly statically typed language, while C# is a strongly statically typed system with dynamic typing extensions (virtual methods in classes).
Second — the ‘var’ keyword isn’t a manifestation of either dynamic or weak typing. It’s simply a signal to the compiler to infer the static type instead of having it declared by the programmer. The compiler still knows the precise type of the variable at the point of declaration, and can still perform all the type-related consistency checks that static-typing mavens like, it just allows the programmer to not have to babysit the compiler quite as much in the process.
In summery, type inference is hardly a “step back”. Indeed, its a step towards becoming civilized for C#.
I guess we posted at the same time so I didn’t see your post.
Yeah, the end product code is just as good as when these variables are strongly typed. My issue is code readability. That’s why perl has the moniker “Write once, read never”. You can do more with one line of perl code then 10000 lines of C code But Lord have mercy if you ever want to read that one line of perl code. There are enough weird bugs in software that we don’t need something like this that OBSCURES what the variable type is to the programmer.
If you’re actually advocating adding scripting language-type syntax to C#. Then give me your home address so I can send you some explosives.
Edited 2006-03-08 18:42
Python is “write once, read easily always” and it also has implicit, strong types. It avoids Perl’s problems by disallowing assignment in if and while conditionals. Also, you can’t “get” from a previously undeclared variable — you can only “set”. It works very well, and is not error-prone.
PERL is a write-only language because it sucks, not because of the inherent disadvantage of type inferencing. Lots of languages a whole lot better than C# (from ML to Clean to Lisp) elide type declarators whenever possible. It doesn’t make code harder to read, once you get used to it, it just makes static typing less of a pain in the ass when you have to modify code.
“In a strongly typed language, it is impossible to subvert the type system.”
** Moron Alert ** Raise Shields **
It’s this new-fangled language feature called “casting”…
uint a = 3;
int b = (int)a;
Or for those Java 5/ .NET heads:
Object o = “test”;
String s = (String)o;
That’s not subverting it. This is:
int a = 5;
void *b = a;
float *c = (float *)b;
fload d = *c;
See how that’s a problem? Conversions actually convert.
Which is why c and java aren’t considered to be very strongly typed languages. Look at ada for a good example of a strongly typed language.
In both Java and C#, subversion of will be detected. The difference between static and dynamic typing is in when that detection and the resultant error occurs. In statically typed languages like ML, the compiler catches it, and issues a compile-time error. In dynamically-typed languages, like the object-oriented parts of C# and Java, the runtime catches it, and issues an error. In weakly-typed languages, the error is not caught, and you get garbage or a program crash as the result.
The intermixing of signed/unsigned values in C# is a poor example because it requires explicit casting. There’s no automatic promotion of signed/unsigned values, so the explicit cast is not significantly different than a function uint_to_int mapping values of type uint to values of type int in a predefined manner. The sanctity of the type system is preserved, even if the mapping isn’t an especially intelligent one.
Upcasting is only slightly more interesting in C# because it doesn’t require explicit coercion and since methods aren’t necessarily polymorphic it’s possible (though it must be made possible explicitly through method annotation) to define methods with duplicate names that aren’t polymorphic, that result in the invoking of the superclass’s method when a reference is coerced to the type of a superclass.
Downcasting is intuitively type-safe on the grounds that it returns a value of the correct type or raises an exception. It is more an element of dynamic typing than a subversion of the type system. Languages without any RTTI to guarantee the soundness of the coercion wouldn’t be considered “strongly typed” given the provided criteria.
You should have brought up implicit conversion operators instead, which would have made for a more interesting discussion.
Basically, they managed to copy Boo ( http://boo.codehaus.org/ ) type inferencing and totally botch it by requiring a var keyword before.
They also copied property initializers from boo. we’ve had that from the start. Though I admit their syntax is better. I made a few changes in my copy of the boo parser to make it look like that.
We’ve also got extension methods, though the syntax is under revision.
LINQ looks cool, but eh.
That’s a little bit presumptuous of you. Languages have had type inferencing before Boo or .NET were even a gleam in some engineer’s eye.
Basically, they managed to copy Boo ( http://boo.codehaus.org/ ) type inferencing (…) They also copied property initializers from boo.
Well, I think it’s a good thing they copy useful features from other languages . The ‘botching’ doesn’t seem to be too grave.
I think these features were just ‘in the air’: some of the stuff reminds me of the languages Nice and Nemerle.
Well, I think it’s a good thing they copy useful features from other languages .
What other languages would you be talking about? Any languages designed for .Net only differ by their syntax.
If you can make some cosmetic changes to C# and get features already built into Boo and Nemerle then .Net is simply not a multi-language environment, as I’ve said many times before. .Net language neutrality is crap.
Well, I think it’s a good thing they copy useful features from other languages .
What other languages would you be talking about? Any languages designed for .Net only differ by their syntax.
Well, in general, languages that already had the new stuff they now added to C#. ‘Nice’ is a JRE-based one that came to my mind, though it certainly isn’t the first or most important and probably not the best either .
If you can make some cosmetic changes to C# and get features already built into Boo and Nemerle then .Net is simply not a multi-language environment, as I’ve said many times before. .Net language neutrality is crap.
Are you saying that things like type inference are ‘cosmetic changes’ and thus cannot be relevant? I must strongly disagree.
As for whether .Net “language neutrality” is crap, I don’t know it intimately enough to be able to say anything about it, but I wouldn’t be surprised if it indeed is.
It is possible to target the .NET VM in such a manner as to provide semantics that do not parallel C#. If you diverge significantly from the featureset provided by C# or the CLS then interoperability is curtailed, regardless of the implementation strategy used to provide the featureset. A C# programmer isn’t going to use a library written to make use of currying or non-strict evaluation because of the size of the code that would be needed to create the datastructures necessary. An ML programmer is similarly going to be irritated by having every reference type from the .NET world wrapped in the Option type to contend with all of those null references. A language where passing bignums around transparently isn’t going to map well to the mindset of a C# programmer that thinks 32/64 bits is enough for anyone. A language where a class is completely mutable at runtime is going to map rather poorly to C# where the methods or properties an object has isn’t expected to change at runtime. This isn’t specific to the CLR, it’s the nature of different languages. There still exist implementations of these languages preserving these differences in various states of completion for the CLR.
This reeks of a scriptling language feature, and will make code reading more difficult. Dumb idea, however the object initializers change seems cool. The anonymous types feature seems to be an extension of the dumb var idea.
I don’t have anything against scripting languages, it’s just that they should be seperate from strongly typed ones. Features like anonymous types and var should be used for VB.net, not C#.
As a time-saver, var is fine as it should be obvious what the type is based on the right-hand side. What’s more, it’ll encourage developers to explicitly supply default values for all their types, which is a good thing.
It’s debateable how much time it will actually save though. In the vast majority of IDEs, one can simply type
Person p = new
and hit [Ctrl]-[Space] and the IDE will suggest all possible classes, reducing the amount of typing somewhat.
It’s also slightly messy that both var, and the explicit types can be used in the same method body. I’d rather they went the whole hog and allowed:
var a = 4;
var b = (4 as LongInt);
var c as float = 3.2;
var d as IPerson = new Employee();
where as would act as a casting operator like in modern versions of Pascal.
As for anonymous classes, they tie in very well with the LINQ project, but I am slightly dubious of their worth. I think it’s better for people to describe what they’re doing in as much detail as possible, to ease maintainance down the road (so you can still infer the original intention from a possibly bad implementation). With anonymous types there’s an awful lot going on under the hood. I’d rather define the Person class, even locally, and then use that rather than have one be whipped up for me.
However, I do commend Microsoft for the amount of innovation they’ve shown with C#: version 2.0 was the first mainstream fully object-orientated language out there and version 3.0 will have a lot of ideas borrowed from the functional programming world, including closures and lambda expressions. By being careful in the syntax they’ve chosen, and the terminology (anonymous method sounds so much more accessible than lambda expression), they’re finally introducing these great concepts to the average programmer.
It’ll be interesting to see how it all pans out.
> It’s debateable how much time it will actually save though.
None for writing but it will save time for reading: fewer keystroke to read –> better readability.
In C++ quite often you have.
HugeHumongousType myVar = new HugeHumongousType(<parameters>);
When HugeHumongousType is is bigger than 40 characters (usually due to templates), duplicating the typename reduce readability without gaining anything so
var myVar = new HugeHumongousType(<parameters>);
will be much more readable.
Reducing the amount of character to read improves readability sure you can go too far like in APL or Perl, but I don’t think that C# var (which existed quite a long time ago in Plan9’s Limbo language, with a better syntax) is going too far.
Then you obviously aren’t understanding exactly what var is for: An explanation straight from the man himself if anyone is interested: http://channel9.msdn.com/showpost.aspx?postid=114680.
I’m very surprised the article didn’t even mention LINQ (well, he said it would be another post; the author should have at least mentioned it), which will be the main place to use the var keyword.
The reason why it reaks of scripting language is because it is one … remember, we’re talking about .NET not a programming language.
.NET binaries are converted to raw machine code.
A scripting language, on the other hand use an interpreter.
.NET is not a scripting framework.
Converted via JIT. And only at runtime while the original file is still a script … ala still a scripting framework.
yes, it is JITed, does this matter? it has all the speed of a compiled language, and the good features of an interpreted language.
http://en.wikipedia.org/wiki/Script_language
According to this “there is no clear delineation between the two.”
IMHO, there is the clear deliniation. Scripting languages are languages usually run by a native program (an interpreter). This is why scripting languages are so portable. All you need to port is the ‘runner’ program.
Compiled languages, on the other hand, use machine code to do what they want. The issue of compiling at execution time and compiling before hand is irrelevant. In fact, .net languages can be compiled befor execution. I believe it is called AOT. However, this is pretty pointless and not done very much as it makes the binary only work on the target platform.
.NET is not a scripting platform.
Not sure what AOT stands for, but you can pre-compile .Net code using ngen.exe (native image generation), and there are switches to optimize the code for different environmental factors (namely processor). Generally speaking ngen’ing is not a recommended practice, but there are edge cases where you can get substantial performance benefits by doing this.
It’s generally a good idea to let the .Net framework compile on the fly as it will make adjustments on the fly to better optimize the code for the environment its running in; the performance overhead (which is negligible) is worth it as in the end you get faster code.
Regardless, you are correct and the parent poster is incorrect (and clueless). By the time it is executed (regardless if it’s ngen’ed or not), all .Net code is fully compiled…it is 100% not even close to an interpreted language. Java on the other hand is interpreted (though there are plenty of precompilers out there, and one may even ship w/ the sdk at this point, I have no idea though) on the fly, but generally exhibits similar performance stats to a compiled language due to the effeciency of the JVM.
i would swear that both Java/C# are similar: compile to bytecode. Then compile JIT that bytecode to native code at runtime or interpret it (probably the JVM mix both) or generate native binaries.
Edited 2006-03-09 09:28
> Not sure what AOT stands, but you can pre-compile .
AOT means “Ahead Of Time” compilation. It’s basically traditional compilation done just prior to execution (e.g. during installation or at load time).
> Java on the other hand is interpreted (though there
> are plenty of precompilers out there, and one may
> even ship w/ the sdk at this point, I have no idea
> though)
NO, NO, NO…. How long is this misconception going to last. Java is NOT an interpreted language – period! The language specification and the JVM specification do not mandate any particular execution strategy. It is correct that the very first versions of Java (back in the JDK 1.0 days) only used interpretation, however JIT compilers were soon introduced and today a wide range of different Java execution engines (as I prefer to call them) exist on the market ranging from pure JIT-compilers, adaptive/dynamic compilers, mix-mode execution engines and all the way to AOT or static compilers (like gcj). Sun’s own JVM implementation (Hotspot) includes as very advanced adaptive compiler (actual several compilers!) that combines interpretation with dynamic compilation- a very effective solution. Pure interpretation of Java is today only seen in very resource-constrained devices (e.g. embedded system and JavaCard), and even devices like mobile phones are using some kind of run-time compilation for their Java execution.
But on the other hand, why should there be any differences between Java and .NET/CLR on this point when you take into consideration that .NET basically is just a very poor masked Java clone.
/Jesper
I’ve had this argument a lot. Technically, Java is not interpretted. However, you still incur many of the disadvantages and advantages of interpretted languages:
1.) Loss of execution speed.
2.) Gain in easy portability
Anyway, I’m not sure how correct this is but it makes sense: According to wikipedia, being interpreted has nothing to do with the language design and everything to do with the language implementation. For example, Lisp implementations commonly allow for interpretation or native execution. They also mention that to be interpreted it has to do go from source.
Java may not be intepreted but it wreaks of it in to me! Although I don’t consider being interpreted to be a bad thing.
You might want to tell else what definition you are using for “scripting language” because it seems to be different than everybody elses. Scripting language is a pretty vague term which really refers to usage over implementation. It has come to mean dynamic, interpreted languages like Perl, Python, and Ruby.
Your definition seems to be “interpreted”. Is Java a script language since it is interpreted? Most people would not consider Java to be a scripting language. However, JPython or IronPython are would be scripting languages. Some languages like Lisp, Scheme, or Smalltalk are definitely in the fuzzy boundary since they are usually interpreted, are dynamic, but can be compiled.
Some languages like Lisp, Scheme, or Smalltalk are definitely in the fuzzy boundary since they are usually interpreted, are dynamic, but can be compiled.
All the languages you mentioned are usually compiled. Out of all the major free Lisp environments, only one (clisp) is interpreted. Out of all the major Smalltalk environments, only Squeek is interpreted. There are more interpreters for Scheme, but the majority of environments for it are still compiled.
I’m not really familiar with C# (I used it a little for about a week back when it first came out, but then I moved away from windows development and haven’t had any reason to go back), but I’m wondering if the var keyword could be used to create something similar to basic C++ templates? I know the example specifically says that var b; b=10; types of things won’t work, but what about var used in a function like so:
void dosomething( var i ) { i.blah(); }
It seems like the compiler could figure out what type var should be whenever dosomething() is used and thus allow a certain type of generic programming. Of course I’m probably way off base here… 🙂
void dosomething( var i ) { i.blah(); }
That would be a good candidate if dosomething was expecting an anonymous type/function as a parameter, but if you’re simply trying to pass in a “typical” parameter, the object type would more than likely suffice, just cast it to what you need inside the function.
No, C# only supports local type-inferencing where it infers the type of a local variable based on its initial value.
You can easily achieve what you’re talking about above by saying
void something (IBlahable i) { i.blah(); }
By using explicit types for class properties and method parameters and results, you can use the var keyword as follows
var a = GetNumPaddingChars (” hello “);
var b = myObject.propertyName;
If C# allowed var to be used for parameters, it would no longer be a statically-typed language as it could not determine the types of all variables at compile time. This means exchanging compile-time errors for runtime errors, and other weirdness (I’m not a fan of dynamically typed languages – see the most recent Java/RoR article for more of my opinions on this)
You aren’t going to save real time via typing. If a 50% reduction in typing were to result the time saved in producing a program would be tiny: Programmers don’t spend most of their time typing the program out once.
Anyway, I think var makes a lot more sense when it comes to LINQ. On its own it’s largely a useless feature. If you want dynamic typing in .net, look into ironpython. That’s real live dynamic typing, as opposed to replacing ‘var’ with the typename at compile time.
Anyway, I’m not sure you’d really want dynamic typing in c#. I’ve not yet decided if it’s a wholly good thing or if it’s just really nice on small programs!
‘Var’ is a big timesaver in two cases:
1) When refactoring code. In most object-oriented programs, there is lots of code that handles an object between when it is created and when it is used. Logically, changing the type of the object shouldn’t affect such code, but it usually does because of type declarations in temporary variables, arguments, etc. Using ‘var’ eliminates a lot of that mess during refactoring.
2) When types become obtuse and the programmer doesn’t really care about the type of a variable anyway. Ever try storing a lambda expression to a variable in C++? The type gets very hairy, and in the end, you don’t care anyway. The C++ standards group is considering something like ‘var’ (an overload of the ‘auto’ keyword), that would alleviate this problem.
Yea, I could see how it’d make sense for number 1. Never used lambda expressions, so I can’t speak on 2!
This all reminds me of Homer Simpson’s concrete grill fiasco that turned into a modernist sculpture. They’re throwing everything and the kitchen sink too into this language.
“Extension methods
Another cool thing is that you’re able to add (static) methods to existing (default) classes. ”
I think this will be really helpful in coding as a team ( eg multiple programmers can use the existing and known String class; Stress is on “known” word, the programmer need not use a new class; when required they can used the extended facility) we can achieve the same functonality by extending the class, but that would result in a different class name as against the “known” name ( eg String and StringWithMD5 ).
This can also be helpful in enhancing an already written code- same argument as above.
Does Java have any similar feature ??
Let’s see,
var s = 1;
var o = { Name: “Niek”, Gender: “Male”, Active: true };
String.prototype.toMD5 = function() { … };
I must say that it really reminds me of javascript (the above is javascript doing roughly the same), but with the added benefit of being a compiled language.
Those are some quite cool features to include in a non-script language.
I can see how the “var” keyword can save time during programming.
However, one hopes that a piece of code is written only once. After that, it has to be maintained, modified, upgraded, etc.
For the life of me, I can’t see how “var” does not hurt the maintainance of code. I agree completely with those who say it makes the code less readable.
Even if it is designed for a special circumstance (LINQ), and even if it is immensely useful for that purpose, people are now presenting it as a general-purpose construct that saves the creator time.
If this is the situation now, imagine the result when abuse sets in.
Am I wrong?
That’s hard to say, I think that var will make code shorter to read so this should help maintainability.
Now OTOH, there could be instance where a type error could be hidden due to var so it could also reduce maintainability. But with *local* type inference I expect that those case will be rare.
IMHO this is a plus, unfortunately Limbo, Scala (other language where there is local type inference) programmers are rare so it’s difficult to get a feedback.
>That’s hard to say, I think that var will make code shorter to read so this should help maintainability.
I can see one case where this doesn’t hold. Something like
var variable = ueberMega31337Function( arg1, arg2, …, argn );
Tell me what kind of a variable does that return without searching for that functions definition.
Good to see C# makes sure it makes the gap larger from the second best general programming language (put yours here).
What I would like to see apart from all those, is optional dynamic lang features, and multiple objects in return (so methods can return many vars and all that).
What I would like to see apart from all those, is optional dynamic lang features, and multiple objects in return (so methods can return many vars and all that).
How is this different from returning a linked list of objects, or else a class containing these objects?
Convenience.
int a;
int b;
/*….blah blah blah….*/
return (a, b)
See, no extra definitions to do it. It looks ugly to people designing larger systems, and for public interfaces it’s often a bad idea, but for internal interfaces it can be really handy.
It looks ugly to certain people because they’re not used to it. They have a need for multiple value returns, but because most mainstream languages don’t have them, they’ve come up with work-arounds and convinced themselves that those work arounds are ‘cleaner’.
Convenience.
int a;
int b;
/*….blah blah blah….*/
return (a, b)
I knew what you meant; I’ve used languages like that (Maple, for instance).
In this instance, a much better solution is to return an array, which is effectively what you’d be doing anyway.
As for convenience, I’d ask: from whose point of view? the writer‘s point of view, or the maintainer‘s point of view? Explicitly declaring an array (or linked list, or class) makes it easier to maintain later on: a programmer doesn’t have to search through the code to find a return statement to know how to handle the result. She need only look at the signature. These things matter.
It’s more convenient and faster. It gets rid of extra code at each and to pack and unpack the data structure, and generally allows the compiler to pass simple parameters back in registers.
It’s more convenient and faster.
I would like to see an example of passing multiple values where the code is more readable to the programmer and maintainer who did not write it than passing just an array, linked list, or class.
I’ve worked with code that returns multiple values, and while it’s convenient to write, it’s not convenient to use. Whatever may have been convenient when writing the code, I’ve always found it more convenient when using or maintaining the code to work with a structure (say) where I don’t have to remember, “Okay, the int is at operand 1, the polynomial at operand 2,” etc. Better to have a structure with explicitly named answers; names are easier to remember than positions.
The phrase “more convenient and faster” does not strike me as a hallmark of quality software engineering. “Faster” is desirable, “more convenient” to the maintainer is even better, “more convenient to the maintainer, and faster” is best of all.
multiple objects in return (so methods can return many vars and all that).
Pass by reference…
public static void Prototype(ref string toModify1, ref string toModify2);
Also… how would you assign from multiple returns… you can only have <variable> = <value>; So, like someone mentioned above, use a linked list (or class) or use my method and pass by reference (just like pointers in C).
Edited 2006-03-09 15:12
The following works in C++ (reference parameters too…)
vector< int > myFunction( int arg1 )
{
vector< int > temp;
for( int i = 0; i < 100; i++ )
{
temp.push_back( arg1 );
}
return temp;
}
I wouldn’t be surprised at all if something similar would work in C#. Though it is more elegant to use reference parameters.
Edited 2006-03-09 16:08
You’re missing the point. What the poster who started this is looking for (whether they realize it or not) are tuples and pattern matching, not the ability to return an array or list.
Actually, in C# the recommended practice is to use out parameters
public static void myFunc (out String toModify1, out String toModify2);
At the moment there’s no semantic difference between out and ref, it just makes it more clear how the function is going to treat those parameters
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cs…
There is a difference, variables passed as out parameters need not have a value yet when the method is called. A method must assign a value to all out parameters before returning, but this is not the case for ref parameters.
But I would prefer being able to return tuples easily to using out parameters, it feels too much like a hack for interop.
This evolving C# business is ONE BIG TRAP — the law of saturation of language’s degrees of freedom in a large project will ensure that a lot of suckers will be sucked in into this MS vortex …
Just think how many books will be written…