I sometimes (often, actually) regress a few years mentally and forget to take advantage of new features afforded by the tools I'm using. In this case, we're using the latest and greatest version of C#, which offers implicitly typed local variables. While working on Stack Overflow, I was absolutely thrilled to be able to refactor this code:
StringBuilder sb = new StringBuilder(256); UTF8Encoding e = new UTF8Encoding(); MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
Into this:
var sb = new StringBuilder(256); var e = new UTF8Encoding(); var md5 = new MD5CryptoServiceProvider();
It's not dynamic typing, per se; C# is still very much a statically typed language. It's more of a compiler trick, a baby step toward a world of Static Typing Where Possible, and Dynamic Typing When Needed.
This may be a cheap parlor compiler trick, but it's a welcome one. While writing C# code, I sometimes felt like I had entered the Department of Redundancy Department.
Sure, there are times when failing to explicitly declare the type of an object can hurt the readability and maintainability of your code. But having the option to implicitly declare type can be a huge quality of life improvement for everyday coding, too.
There's always a tradeoff between verbosity and conciseness, but I have an awfully hard time defending the unnecessarily verbose way objects were typically declared in C# and Java.
BufferedReader br = new BufferedReader (new FileReader(name));
Who came up with this stuff?
Is there really any doubt what type of the variable br is? Does it help anyone, ever, to require another BufferedReader on the front of that line? This has bothered me for years, but it was an itch I just couldn't scratch. Until now.
If that makes sense to you, why not infer more fundamental data types, too?
var url = "http://tinyurl.com/5pfvvy";
var maxentries = 5;
var pi = 3.14159;
var n = new int[] {1, 2, 3};
I use implicit variable typing whenever and wherever it makes my code more concise. Anything that removes redundancy from our code should be aggressively pursued -- up to and including switching languages.
You might even say implicit variable typing is a gateway drug to more dynamically typed languages. And that's a good thing.
I personally agree that we should not have to worry so much about the details of converting and setting up variables and more on what we do with them.
As compilers get better at figuring out what type of variable we want, we can be distracted less by variables and focus more on building the solutions.
Jeff Davis on June 20, 2008 7:48 AMBesides ... usually by typing 2 or three characters I can hit tab and get the declaration I want anyway.
N on June 20, 2008 7:48 AMI think you have forgotten about abstraction and using base classes to access derived classes. You probabably haven't but the power of polymorphism is the gained poewr that makes those syntactic elements necessary.
If you were going to rail against something, why not the redundancy you see in naming things like this:
ArrayList PersonList = new ArrayList();
where the identifier name is indicating implementation - this could have been:
ArrayList People = new ArrayList();
--/\/\ike
mikester on June 20, 2008 7:48 AMJust a thought.. why not remove the keyword var also?? So instead of var v = new myobject() v = new myobject()
paramesh on June 20, 2008 7:50 AMAs compilers get better at figuring out what type of variable we want, we can be distracted less by variables and focus more on building the solutions.
They don't, it's just that the C# and Java compilers suck balls. Compilers in more advanced languages (Haskell, OCaml, Scala) have been able to do not only local type inference but also non-local (e.g. function or method-level) for a long, long time.
masklinn on June 20, 2008 7:50 AMJust a thought.. why not remove the keyword var also?? So instead of var v = new myobject() v = new myobject()
Because var is used to disambiguate between creating a new variable in this scope and reusing an existing variable in an upper scope. It's actually one of the things I regret lacks in Python, it makes scoping and scope handling clearer and simpler at an essentially nul cost.
masklinn on June 20, 2008 7:52 AM@Grandpa Coder
I don't think you understand how var works. It *doesn't* push type checking to run-time. The only difference is that the type is declared by the right side of the assignment operator, not the left:
StringBuilder x1 = new StringBuilder();
var x2 = new StringBuilder();
Both x1 and x2 are StringBuilders and are declared as such. The following lines cause the same compiler error:
x1.Foo();
x2.Foo();
You don't lose any compile time checking, the IL code is actually identical.
Personally, I love type inferencing, though I would say that it's not so much a gateway drug to dynamic languages, but a gateway drug to functional languages (such as F#) which use type inferencing almost exclusively.
Adam on June 20, 2008 8:04 AMHow do you do this with your new cool C# syntax:
List list = new ArrayList();
Something isn't clear about:
var list = new ArrayList();
I guess list variable's type will be ArrayList and now you may accidentally invoke something special to that implementation of List. Isn't it violating the "program to interface" philosophy (or whatever)? I am not in either the strong-typing or weak-typing gang. I'm just curious.
And I am not sure this is a great feature for a strongly typed language like C#. Seems like it's going to make average programmers' life (and the people who review their code) tough. Of course, such type of programmers don't even know what is "programming to interface."
(Don't know C#'s library classes, the above example is in Java.)
-- Srikanth
Srikanth on June 20, 2008 8:06 AMWhat is this C# stuff? I thought you "don't enjoy parsing through C#, and any C# code I plan to incorporate into my new projects, I *always* convert to VB.Net". (http://www.codinghorror.com/blog/archives/000128.html)
Anyway, to me, things like this are the primary reason to stick with VB. It's not trendy, but it sure provides a much smoother ride.
MattH on June 20, 2008 8:09 AMDuh... The simple solution here is just never name any of your classes or types over two letters long. That way "var" becomes the long name!!
h c = new h(); //FTW!!
var p = new mc(); //FTL!
To all those complaining about using base class declaration, I think you're missing the point.
In local scope, you should rarely ever care about a base class at the point of declaration. That's only going to be important when you pass the variable off to another method.
AbstractBaseClass c = new ConcreteClass();
This doesn't buy you anything within a local scope. Within this scope your code will always, by definition, know about the concrete class. If you have some code further down that is going to break by declaring c as ConcreteClass instead of AbstractBaseClass, then you have some refactoring to do.
Adam on June 20, 2008 8:12 AMJust one more thing Jeff,
between:
var maxentries = 5;
and
int maxentries = 5;
I have trouble seeing which one is more concise... But there is one that is crystal clear ;)
I agree with the idea that 'var' is nice is some cases (declaration = instantiation) but in some other it is no (simple types, values returned for functions...). For arrays I have to say that I'm not sure...
Philippe on June 20, 2008 8:14 AMI agree with the use of var in cases where you're using "new" and want the same exact type that follows the "new", and it's totally obvious what that type is. The reason is that it makes the code more readable. If there's a lengthy type name (as often happens when using generics), and it's repeated twice in a row, that's more crap I need to parse while reading, and having it repeated doesn't buy me a thing over using var. Then put a bunch of lines like that together in a row.
So, var is worth using in some non-required cases for the sake readability. It just takes a little discretion on the part of the programmer. When I see it abused, I don't curse the language designers, but rather the programmer who abused it - or the person who refuses to fire that programmer.
By the way, those of you who said or agreed with "now we just need to get rid of var!" - that's just stupid. If you don't want a compiler to help you, go use a language that doesn't have one. And using var for cases where you don't specify the type right after the var but easily could have? (like base types) It makes the code less readable and more error-prone, IMO. You'd better specify that type somewhere.
Tom on June 20, 2008 8:15 AMHi Jeff,
You should totally check out haXe, it has this sort of inference since very long time.
Also you can compile your code to swf, js and server-side bytecode (that runs on its own VM called Neko).
Check the site out:
http://haxe.org/doc/intro
http://nekovm.org/
Cheers!
Zarate on June 20, 2008 8:18 AMWell if only now you could eliminate the left over redundancy of, well "var" itself, we'd be in business.
What do you need to know its a var, when the parser hits text, thats not in the symbol table, its a var. Yes it makes the compiler less efficient, but us being faster, is a good trade off.
Chris on June 20, 2008 8:20 AMI'm sorry, but I have never been a huge fan of impicit variables on any type of big or major project. Call me old school (although I'm 24 and haven't used C++ since my 2nd year of college), but I remember doing big project in PERL and running into huge issues because of this. VB.NET syntax has annoyed me since inception.
I agree, there is too much redundancy with Java for example in declarations, but I think some of the new languages have taken it too far and have severely hurt readability in order to save a word here or there.
Honestly, whats the difference between "int i = 0;" and "var i = 0;". Especially when you run into issues of doubles, floats, ints, and longs ... its hell.
My 2 cents
Another Programmer on June 20, 2008 8:23 AMI guess list variable's type will be ArrayList and now you may accidentally invoke something special to that implementation of List. Isn't it violating the "program to interface" philosophy (or whatever)? I am not in either the strong-typing or weak-typing gang. I'm just curious.
Given that it's within the body of a function, it doesn't matter one way or the other. The part where coding to interface not impl is important is on the interface of the functions (parameters and return values). Since C# doesn't do nonlocal type inference that's a non-issue: you still specify explicitly the types of your inputs and outputs.
And I am not sure this is a great feature for a strongly typed language like C#.
1. This feature has nothing to do with strong typing. At all. Whatever "strong typing" means to you (of the dozens of more or less hazy definitions of the term)
2. Type inference is related to *static* typing (where types are resolved at compile-time, rather than run-time type resolution in dynamically typed languages) and languages infinitely more statically typed that C# (as in, languages where "null" doesn't even exist and the "nullability" of a variable is a type in and of itself, or languages where side-effects have to be encoded in the types of your funtions, and languages where you aren't allowed to add a float and an integer without an explicit conversion) have had type inference (of a much more impressive and wide-ranged breadth than that added to C#) for years.
Type inference exists solely and uniquely for statically typed languages by the way, it doesn't really make sense for a dynamically typed language. And it isn't of much use either, beyond basic static analysis and potential optimizations.
masklinn on June 20, 2008 8:31 AMI welcome the addition of type inference to C#. Anything that can reduce unnecessary redundancy is a good thing. But I wonder if a better, more general, solution would have been to introduce a typedef construct into the language. Actually, I wouldn't mind having both.
Ferruccio on June 20, 2008 8:35 AMCall me old school
As I said, that vision is not "old school", it's "uneducated". Implicit typing, be it dynamic or static, has existed ever since languages of a higher level than raw assembly have existed.
Honestly, whats the difference between "int i = 0;" and "var i = 0;".
There is none, but there is a difference between
MapSetString, ListListFrobBar, Grutz myMap = new HashMapSetString, ListListFrobBar, Grutz();
and
var myMap = new HashMapSetString, ListListFrobBar, Grutz();
That's a pathological case, but it's trivial to encounter cases that come close to that when using generics and trying to leverage the type system for safety.
masklinn on June 20, 2008 8:36 AMI would also like to say that I agree with DomreiRoam that if you really wanted to cut redundancy, it would be nicer to do it on the new statements (ie Listfoo bar = new() ).
However, the main point of the var keyword is to provide type checking for anonymous variables and other similar cases. To my mind, using this to cut redundancy is somewhat of an abuse of the language.
ricree on June 20, 2008 8:41 AMvar myReader = new Reader() is unambiguous
However
var pi = 3.1415 is ambiguous (is a decimal? float? double?)
Wile_E_Coyote on June 20, 2008 8:50 AMAnother Programmmer,
You're so right. While on the topic, what's the difference between "StarlightFightingWeapon x = new StarlightFightingWeapon" and "x = new StarlightFightingWeapon"?
Oh...24 characters. Hm.
Grace on June 20, 2008 8:51 AMAnyone typing the class declaration twice in C# is wasting keystrokes. The IDE is your friend.
type: MyClass variableName = new [tab-key].
Done. You now have everything you need to proceed *and* readable type declarations. Personally I dislike var. Just because the compiler is smart and can figure out what type that var is doesn't mean this code is somehow more readable to me, the human involved.
In the case of C# we have a pretty good IDE in VisualStudio and I'd rather that Microsoft spend energy making the IDE more powerful, rather than changing the language to be more dynamic-ish.
There are several good dynamic languages out there. What would be better than debasing C# is to port something like Ruby to VS and CLR.
Michael on June 20, 2008 8:53 AMHere's a thought, let's infer the datatype from the first character of the variable name. "I" thru "N" are integers and everything else is Floating point... oh wait, I'm showing my age.
Wile_E_Coyote on June 20, 2008 8:53 AMIt should feel wrong. The '1' can be a byte, sbyte, short, ushort, int, uint, long, ulong. It makes a difference what type it is.
But why can't the 1 simply grow/size to fit? Wouldn't that be preferable to the overspecific data typing and the inevitable integer overflow weirdnesses errors and even *exploits* this results in?
Jeff Atwood on June 20, 2008 8:55 AMI'm in the 'no sir I don't like' group. It has it's place certainly like with LINQ (for which it was introduced). However I think it's overuse will be something we look back at with disdain in a year or two. I do sincerely hope though that authors (blog and print) will shy away from it when showing code examples.
Ryan C Smith on June 20, 2008 8:55 AMIf keeping declarations short helps with readability, then I'd propose limiting all the variable names to six characters and adopting a convention where integers have names starting with the letters I through L and everything else is assumed to be a REAL. (Or you could just go to www.lahey.com and buy a Fortran compiler. I believe they have one for .Net.)
My problem with this scheme is that the style for declaring variables isn't consistent. Sometimes you declare ComplexObjectType as ComplexObjectType (e.g. when it's coming from a factory), sometimes you declare it as a var because ComplexObjectType will appear on the right side of an equal sign.
This leads to some mental gymnastics when you're deciding which style to use, and more gymnastics when you go to maintain the code six months from now.
Worse, when a junior coder comes along and sees this abuse of the anonymous type, [s]he might not realize the conditions of the coding style. Then you end up with something like
var object = Server.Create()
because the junior person simply didn't know better.
I agree, typing something like
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
seems needlessly verbose, but if you're using Visual Studio (or, I'd hope, pretty much any other IDE) Intellisense is going to kick in and type everything after the new for you.
IMHO, the minimal time savings from using the anonymous type isn't justified when you compare it to the maintenance hassles.
Blair on June 20, 2008 8:56 AMI find this post very funny considering that the last entry was "Coding for Violent Psychopats".
Also, how hard is to write StringBuilder instead of var on Visual Studio, you just hit CTRL + SPACE and the IDE does it for you.
The problem with this "var" keyword is that while it may sound nice in your example it is going to be overused and it will make code maintenance a nightmare.
Mike G on June 20, 2008 8:57 AM(TSK seems to be the first to make the point I wanted to make about declaring a field to be a supertype and then assigning it to an instance of a subtype.)
I can't support any type inference or type omission scheme that fails to handle that case. How many times do you want an API to specify that a method returns a type T and not let the fact that your implementation returns type S (where S is a subtype of T) become available to clients of the API?
"BufferedReader reader = new BufferedReader(...)" isn't redundant; it's specifying that two completely different things happen to be BufferedReaders. I do agree, though, that it appears often enough that there should be some syntactic sugar enabling this form to be shorter.
Nathaniel Manista on June 20, 2008 8:57 AMThe more I think about it, and the more examples I see, the more I think _var_ was a terrible mistake.
This is doubly so for people who are insane enough to advocate eliminating even the _var_ keyword. Suppose you have a large class. In a method you have the line:
actionResult = false;
Is that a declaration/initialization or an assignment? What's the scope of that variable? Depending on an IDE to tell you these things is a language fault and overly shortsighted.
But hey, just my opinion. I'll keep writing clear, readable, and unambiguous code.
Nick on June 20, 2008 8:57 AMI believe you have missed the boat on this one Jeff.
Explicit type casting is there for a reason. It lets the compiler know what we want to have in the variable, what should be in the variable, and it can help identify problems when they occur. Your examples are a bit simple too. There are more times when I am assigning a variable from a return function whose return value isn't always clear. Also keep in mind that the constructor doesn't always reflect what is being constructed.
Also, just having the type out in front makes it even easier to read.
Phil on June 20, 2008 8:59 AMUnfortunately, you and everyone else pretty much got it wrong. While I agree with you that redundancy is not a good thing, the better way to solve this issue would have been to do something like the following:
MyObject m = new();
Or if you are passing parameters:
Person p = new("FirstName", "LastName);
Where in the creation of a new object, the compiler infers the type from the left-hand side, and not the right. This has other advantages over "var", in that it could be used in field declarations as well (there are also some other areas that it could be useful as well, but I won't get into it here).
In the end, it just wasn't intended to reduce redundancy. Don't get me wrong, "var" is VERY important in C# for anonymous types/projections, but the use here is just WAY off (and I've been saying this for a long, long time) as you obfuscate the type that is being used. Having to type it twice is too often, but declaring it zero times is too few.
Nicholas Paldino [.NET/C# MVP] on June 20, 2008 9:00 AMIn C#, using var for value types is a dangerous shortcut that will come back to haunt you at some point.
Consider:
var i = 1;
is i an int, a uint, a long, a short, an int32, int16, int64?
var pi = 3.1.4159;
is pi a decimal, a single, a double, a float?
What are the boundaries of those variables? How would you write a unit test to cover boundary testing? How could you be sure? And, more importantly, will this behavior change with .Net 4.0? (or 3.6 or whatever they call it).
C# is a strongly typed language. And you need to be aware of strongly typed issues such as boundaries and overflows.
Despite being able to make it look like one, it is not a dynamic language. If you want to use a dynamic language, use one. There are a lot of great dynamic languages out there that can consume the .Net framework these days.
A Flurry of Voices on June 20, 2008 9:06 AMExcept some tendencies to overuse, I am not sure what's not to like.
I, for one, welcome our new type inference overlords.
Seriously, it's a nice language feature in both languages, and it can be misused like any other language feature. It will take a while, but people will learn when to use it and when not to use it.
I can certainly see how auto and ptr would help me write code.
Next thing people will complain about the new closures in C++0x I imagine.
instead of "StringBuilder sb = new StringBuilder(256);" or "var sb = new StringBuilder(256);", I would prefer "StringBuilder sb = new (256);" - you get the variable type explicitly declared, and the constructor implicitly. Seems a lot safer. In the case where you need an abstract base variable with a concrete type, you'd obviously define the concrete type after new, as per usual.
f0dder on June 20, 2008 9:16 AMI'm not a big fan of "var" overuse, either. I've been bitten by the same issues other folks have. I actually take issue with some of the ease of readability, too. For example, a bunch of variables declared in a row, mixing and matching:
IMyInterface a = SomeService.Create();
var b = new XmlDocument();
int c = 7;
I can't just scan down the left side and see the various types; now my eye jumps back and forth from one side to the next, trying to figure out what's going on from a type perspective. And sitting "var" next to "int" makes you look twice, doesn't it? It sounds nitpicky, but if you read a lot of code over the course of a day, it gets really lame really quick.
I really only like "var" in two cases: Anonymous types and really super long type names (like that crazy generic masklinn mentioned above).
Travis Illig on June 20, 2008 9:17 AMAlso, how hard is to write StringBuilder instead of var on Visual Studio, you just hit CTRL + SPACE and the IDE does it for you.
At least you have your fancy IDEs that can do half the thinking for you. Now if only corporate could get rid of the monkeys all together and replace them with really smart IDEs.
How many times do you want an API to specify that a method returns a type T and not let the fact that your implementation returns type S (where S is a subtype of T) become available to clients of the API?
Knowing what you're talking about. You need to try it.
C# type inference is *LOCAL*. It does NOT exist at the API level, it only works *within* a function and doesn't bleed out. *You* are still the one specifying explicitly your API.
Explicit type casting is there for a reason.
Yes, and that reason is lazyness on the part of the compiler writers, and willingness of corporate code monkeys to let them.
It lets the compiler know what we want to have in the variable, what should be in the variable, and it can help identify problems when they occur.
No.
There are more times when I am assigning a variable from a return function whose return value isn't always clear.
Hey, guess what? It's optional. If it makes code less clear, just don't use it. Also, you can leverage your shiny little IDE which you like boasting about so much because it prevents you from thinking: it knows the types of your variables, just ask it.
Or even better, reengineer your functions so that what they return is clear.
is i an int, a uint, a long, a short, an int32, int16, int64?
I know I don't give a fuck in about 95% of the cases.
In the 5% left where I absolutely definitely need to say that something is a short, I can since var is optional.
Then again, I'm used to non-moronic languages where integer types default to unbounded and overflow is an issue gone the way of the dodo.
How would you write a unit test to cover boundary testing?
Testing is done at the boundary interface of a function, C#'s type inference only works within a function. Non-issue.
And you need to be aware of strongly typed issues such as boundaries and overflows.
Despite being able to make it look like one, it is not a dynamic language. If you want to use a dynamic language, use one.
Your lack of knowledge about the field of computer science and computing is astounding and, quite frankly, border on frightening.
You don't even remotely know what you're talking about.
masklinn on June 20, 2008 9:23 AMThe truly amazing thing about this post is the number of comments bashing Jeff where the comment's authors are _completed misinformed on var_.
Not that linking to Dare's post helps, of course. As is not uncommon over there, Dare's post twists off on some particular possibility and makes it sound like it is the mainline case. I have yet to see code, in online samples or in production code, where the use of var causes people to go hungarian, and as much as Dare would like to blame it, R# isn't doing anything to encourage going hungarian.
To people freaking out about using var in place of int: It's simple, just int!
To people freaking out about using var for variables assigned from method returns: It's simple, just declare the type!
To people freaking out about var making your numeric types ambiguous: If they are ambiguous with var, you were writing them incorrectly before anyway.
To people freaking out about var taking away compiler checks: Please leave the industry.
It is VERY easy to set a var usage ruleset for use either personally and/or within a team. Maybe your team likes var everywhere. If so, fine. Maybe just on anonymous types and heavy generics, but never when assigned from a method return. Whatever. Just put in places rules for what you are all comfortable with and run with it for a while. There are trade-offs. There are personal preferences. Surprise, surprise, this is just like any other part of a coding standard. Pull up your big boy pants and get back to work.
Jeremy Gray on June 20, 2008 9:24 AMImplicitly typed local variables on C#? Ok
It just made me wonder how you compared PHP as a mess of functions and how organized is C#. Btw, the idea of listing the functions in php that starts with 'a' was taken from a video of the guys from Django. Right?
Anyway, I guess this video is really nice and pertinent to C# version 3
http://www.railsenvy.com/2007/10/9/ruby-on-rails-vs-net-2
nice comedy ;)
Ow, and your blog and the podcasts with Joel Spolsky are really nice.
Best Regards from Brazil
Dani Berg on June 20, 2008 9:24 AMI think it's funny that you just wrote an article about maintaining code, and now you follow it up by praising a programming convention that was created for lazy people, by lazy people. Your not concerned about the ill-effects of redundancy, your worried about keystrokes. You're like George Bush saying he's worried about terrorists and not oil profits.(FTW!)
I enjoy typing my variables because it reinforces my own understanding of my code and hopefully scares lazy coders into actually thinking.
C'mon, nobody uses Boo? http://boo.codehaus.org/
The code looks like Python, but the compiler is smart enough to do automatic static typing for you. You can declare variable types if you want to, including a "duck" type which works exactly like dynamic variables do in Python. It's a .NET language, too. Best of all worlds.
steve on June 20, 2008 9:28 AMJeff:
Why did you choose to use C# over VB.NET? I thought you were a strong proponent of VB and all it's dynamic glory?
Josh on June 20, 2008 9:29 AMI have to disagree with you on this. In my opinion, omitting those types makes your code harder to read.
Even on the example you wrote, it still takes *longer* to read the shorter code, because I have to scan to the right for each variable to see what it was. Before, if you had
MD5CryptoServiceProvider md5
well, then I'd know what md5 was, and I could skip on to the next line. Now, if you just have 'var md5', I have to read your entire line to figure out what it is; after all, 'md5' could be the provider, a hash itself, or - if you're evil - something totally unrelated. It could even be some class of your own that also has the initials m, d, and 5! Worse, things like 'var e = new UTF8Encoding()' sound as if you simply picked variable names out of the sky, and started assigning them haphazardly to whatever you needed. var e is....eh, let's put the text encoder there! Is it just me, or does 'UTF8Encoding e = new..', connect the two more closely?
But perhaps this is just how I remember variables (int i, List clientList, DatagramSocket socket, etc), so if I'm the only one who finds this weaker, don't worry too much about it. :]
Phillip Cohen on June 20, 2008 9:32 AM[quote]
You should give Python a shot - you don't have to deal with any of this unnecessary verbosity.
Guido van Rossum on June 20, 2008 05:41 AM
[/quote]
Amen :-) I've been doing Python for two years now, and this has never been a problem whether I'm writing new code or maintaining someone else's. Python Just Makes Sense (TM) ;-)
astigmatik on June 20, 2008 9:33 AMUsing var for reference types is also a bad idea. While you won't have the boundary and type-guessing issues that you have with value types, you wind up with more subtle issues. Issues that make your application a lot more rigid than it appears to be on the surface.
"var" gives coding ease and flexibility. But it leads to development rigidity. Consider:
var mylist = new Liststring();
...
foreach(string s in mylist) {...}
mylist is now a Liststring. It can only be that and will only ever be that. But the only thing I ever do to mylist is to enumerate it. The best practice here would have been to declare it as:
IEnumerablestring mylist = new Liststring{};
Now the same code will work regardless of the type that mylist becomes.
In this case, using "var" has decreased the flexibility of your application in a subtle way. This method is now more rigid than it needs to be and will take more time in the future to modify.
This is not a fringe condition.
Coding against interfaces is a commonly accepted Best Practice. If you find yourself declaring a lot of reference types as specific types (or using "var") a lot, you need to stop and consider what you are doing. Odds are you are doing it wrong. Always code against the interface.
"var" saves some typing. Woopty-doo. With intellisense there are very few declarations that take more than three or four keystrokes anyway.
A Flurry of Voices on June 20, 2008 9:37 AM
Jeremy Grey et al:
I'm not misinformed on "var". "var" helps in the writing of code, but hurts the reading of code (or at least it does for me). The key to maintenance is reading code... other people's code (or your own, down the line). We all know how well coding guidelines work, especially when the people writing the code aren't on your team.
var x = SomeObject.SomeMethod();
What type is x? If I'm in the IDE I can find out (with extra work). If I'm in a text file or an email or a netmeeting or an HTML page or anywhere else I have no idea what that is.
I'm using a statically typed language in part because I can easily know what type of a variable is. This hides that.
Craptaculus on June 20, 2008 9:50 AMmylist is now a List. It can only be that and will only ever be that. But the only thing I ever do to mylist is to enumerate it. The best practice here would have been to declare it as:
Er... no. Just change "new List" into "new SomethingElse" and the compiler will reinfer your types, infer that "mylist" is now an instance of "SomethingElse" and check that all other uses are coherent with that. You fail.
And, in fact, a *smart* type inference system (I don't know about C#, but one along the lines of Haskell's) will be able not only to infer types (non-locally, to boot) but it will infer the most general types available. So in the case your talking about, it would even have inferred IEnumerable.
In this case, using "var" has decreased the flexibility of your application in a subtle way. This method is now more rigid than it needs to be and will take more time in the future to modify.
It hasn't in any way, shape or form. Nice try, no sugar, you get an F.
Always code against the interface.
How about "always code with your brain"? You've demonstrating that you're not thinking, only parroting things you don't get. Maybe you should pause for a second and try to get smarter than your IDE.
masklinn on June 20, 2008 9:50 AMI'd like to paraphrase Steve McConnell here (or whoever he was quoting):
Code for people first; compilers second.
To the compiler, it doesn't matter whether you use var or IEnumerableListT, it all looks the same.
To a person, however, the latter is much clearer.
TraumaPony on June 20, 2008 9:52 AMI have to say as a C++ and then/also C# programmer I've always been a little frustrated by the way in which objects are initialised... and the plethora of special purpose objects (e.g. StringBuilder) which are of questionable value. (would providing an 8-bit ANSI char type really have made the language any worse to use? really? made it better maybe?) I think c# tries to hard to be high level...
I have nothing against static typing though... although I find it odd that a more hybrid approach hasn't become the standard. afaik compilers always have enough information to do these sorts of "parlour tricks" and even better things... its a lot of code though, at least in my experience.
.NET has a base object type too... makes it even easier to do. :)
Jheriko on June 20, 2008 9:53 AMOh, and the people using the example
"var pi = 3.14159: float or double?"
If you know anything about C#, you'll know it's a double ;)
And it is a misuse because it goes against the opinions of the language designers.
In the future, I will thank you to please speak for yourself, not for me. You don't know what I think and it is presumptuous and offensive to claim that you do.
I agree with Jeff; removing valueless but hitherto required redundancy is a good thing.
Of course this feature can be misused to create code that is harder to read, understand, and maintain. All language features can be so misused; please refrain from doing so.
Finally, Jeff, I believe that you are somewhat conflating implicit/explicit typing (a LEXICAL characteristic of a language) with static/dynamic typing (a SEMANTIC characteristic of a language). Adding more implicit typing to C# does not move it in the direction of dynamic languages; adding dynamic typing moves it in the direction of dynamic languages.
This is VB Developer speaks in you :) and I hear "VB vs. C#" tones more than I hear "Ruby vs. C#".
What about abstracting classes up? Like TextWriter writer = new StringWriter(). From my point of view, the "var" in its current state is just a useful half-way house for raw types which should be converted to the static types and better sooner than later. Code should be consistent and I pity those who will be maintaining the var-static-mixed code.
I haven't read all the comments (too lazy ...) but isn't most of our time taken up thinking rather than typing? Is it really such a big win to type var (or not) instead of a class name? Lots of people complain about verbosity but from my experience the syntactic 'noise' just disappears from my radar when I read code.
Bedwyr on June 20, 2008 10:37 AMJeff, I hope you won't regret this post in a few months/years ;)
Igor Brejc on June 20, 2008 10:38 AMmasklinn:
Calm down. I think you might be misreading what "A Flurry of Voices" said. By using "IEnumerable mylist" instead of "var mylist", the intent in much clearer (I'm going to be looping over it), and the code that uses "myList" will be easier to modify later because it is defined as "IEnumerable". If you just say "var", the "looping over" intent is not displayed. So, when someone (or you) comes to modify it later, it'll take you longer to figure out why you can't just change it to "new SomethingElse".
Yes, the compiler and IDE will catch it, but it's still extra work compared to simply typing out the interface name and thus your intent.
Also, for your advanced inference system: IEnumerable is an interface, and classes can implement many of them. If a class also implements IEnumerator, what is the type of the variable? Yes, the compiler and IDE knows, but does the guy reading the code?
A sufficiently advanced compiler/parser can infer that IEnumerable is the lowest common interface (or class) for all uses of the variable (ie foreach), but the poor guy modifying your code now has to figure out all the implications of adding another use of the varaible. If he adds passes the variable to a method which accepts a List, does the type change? *Can* he even pass it to the method? The only real way to tell is to try it and let the IDE or compiler tell him.
There's nothing wrong with that in Ruby, Perl, or Haskell, but I choose C# because the intent of code is much clearer. This doesn't help readability.
"Anything that removes redundancy from our code should be aggressively pursued -- up to and including switching languages."
Agreed. And without naming any names, the only languages that I've seen able to do this completely are those where code-is-data, and with a solid metaprogramming facility for generating code at read/build-time -- because those allow you to manipulate anything you wrote in any way.
Every nontrivial program I've ever worked on, in a language with a strict separation of code and data, has always ended up with repeated logic in slightly different forms. Sure, in all cases it's technically possible to extract the common functionality, but without built-in code-generation facilities, it's more work than just inlining each case. C programmers who need to both read and write a data file tend to write one function to read, and one function to write.
Bedwyr, I totally agree. My time is in thinking, not my typing.
To top it off, my thinking is a lot easier if I've spent the time writing and reading explicit code, I will therefore always fully declare everything if I can.
Explicit typing is a major reason I am a fan of C# and not VB / Javascript, etc.
The reason for "var" is it is a requirement to make the most of generics, extensions and linq.
I think they're all great features in the language but my gut feeling is that a lot of people are going to use them without enough thought and cause a lot of headaches further down the line.
Robin Day
http://www.advorto.com
I find it amazing how slowly C# is adopting these features, it is really turning out to be the 'plumbing' language, i.e the language you code to the database with, but leave the business layer up to a more 'agile' CLR language like F# or Iron Python.
Example: The Magnificent language BOO (mentioned already in the comments) has had this from the start, and more besides. It's a true, first class CLR language, that looks like and more importantly programs like python.
In anycase I like to think about the problem space while I type, not the laborious syntax and always having to satisfy Intellisense and Resharper, so these features are welcome.
Andrew on June 20, 2008 10:59 AMI must say that I'm not a big fan of dynamic typing. It just has too much capacity for abuse. I put this in the category of "goto" which, although perfectly valid to use, can lead to confusion and code that is difficult to maintain.
For instance, what would you make of this:
var myval = b.DoSomething();
what is myval? What methods does it support? What methods can I pass it in as a parameter? Can I use it in a printf() format? With intellisense, I probably can quickly find that out, but if I'm reading this code in a diff tool or other text editor, that won't be available.
I disagree.
1. var url = "a href="http://tinyurl.com/5pfvvy"http://tinyurl.com/5pfvvy/a";
2. var maxentries = 5;
3. var pi = 3.14159;
1. string or url? is it obvious? no.
2. int or long? is it obvious? no.
3. float or double? is it obvious? no.
See, the problem is that it may seem obvious to you what the variables should be, because you can see the whole picture and the intent for those variables (and potentially, what their future values will be) but the machine... it may end up having to cast to a new variable type.
I'm all for doing less typing (ie. work) but I'm a big fan of "say what you mean and mean what you say." That includes declaring variables. Why bother being ambiguous and expect some compiler that you didn't make figure it out what you mean. (Because if you didn't write it, it doesn't work... remember?)
Steve-O on June 20, 2008 11:09 AMAgree with Steve-O on this being bad:
1. var url = "http://tinyurl.com/5pfvvy";
2. var maxentries = 5;
3. var pi = 3.14159;
This is a step backwards.
If you're complaining about C/C++/C# syntax in general, I agree. VB.NET is better, and Pascal is pure beauty.
A pet peeve of mine: people who use 'name' and an instance variable of class 'Name'. Off with their fingers!
Steve on June 20, 2008 11:34 AMTo Nicholas Paldino:
It does seem like it would be better to have the compiler infer the type from the LHS like your example:
MyObject m = new();
But I can't agree with you that all of us "got it wrong", because C# doesn't work that way. We have to make the best of what we've got. Personally I think the blog post got it right for the first set of examples, but wrong for the last set of examples.
Ideally the type should be written out in the code exactly once when declaring a new variable and instantiating an object of that type in the same line of code - for maximum readability, maintainability, and safety.
Tom on June 20, 2008 11:43 AMmasklinn had it correctly: too many inbred morons. Jeremy Gray's comment is also worth reading.
One observation (among too many, but some of them have already been made by the two I mentioned above):
---
var i = 1;
is i an int, a uint, a long, a short, an int32, int16, int64?
---
It's an int, idiot. Learn your language. Or, as a faster alternative, use Resharper and write
int i = 1;
It will inform you that you CAN, if you CHOOSE, change that to
var i = 1;
It will NOT do that if you had typed
short i = 1;
in the first place.
Ah. I am trying not to ignore that these people pretend to be programmers.
Oops. Typo. I am trying TO (delete the "not") ignore that these people...
Marcel Popescu on June 20, 2008 11:45 AMvar is useful and the confusion can be easy avoided
first of all: the difference between int and long? yeah? in which C?
you use float instead of double? why?
there are 8 types of integers (including signed/unsigned and not counting long), 2 (theoretically 3) real types and no equivalent for sql money? whatever.
an language must help the programmer (at least their expectations :), so when you type:
var i = 2;
var x = 3.14;
var c = 'a';
90% you will expect/want/need
int 32b signed i
double x
char signed c
want unsigned int? var x = 3u; or var x = uint32(3);
float? var a = 3.14f; or var a = float(3.14);
and so on...
about pointer to 0... NULL == 0 ? big mistake,
NULL should be (void *)0
This kind of article makes me lower my opinion about the quality of your analysis.
This is one step further bad coding practices, it will make reading code more difficult and will be more likely to hide errors. C# was clean, they are making it look more like VB which is a shit language.
I think you just jumped the shark to me.
Fab on June 20, 2008 11:52 AM@Andrew
"I find it amazing how slowly C# is adopting these features,"
Then again, look at java. Compared to it, C# is adapting at a blazing speed. I'll bet a lot of this has to do with the existing code base. if you Microsoft or Sun, you can't just change everything to the latest greatest whenever you want to, whereas when designing a new language from scratch, you can!
I attended a "What's new in C# 3.0" session at Austin.net CodeCamp a month or so ago, and I doubt there was a person in that (very full) room that didn't rejoice about this new feature. But, as with any other language feature, you, the programmer, need to be aware of what it does and use it when appropriate.
One of the other new C# features I love even more than this is automatic properties!
Dennis on June 20, 2008 11:53 AMI am all about concise code, but this syntax is necessary for OOP and polymorphism. Allowing stuff like this:
public BaseClass obj1 = new ExtendedClass1();
public BaseClass obj2 = new ExtendedClass2();
if(obj1 obj2)
DoSomething();
Is the compiler smart enough to make this work with var?
Jesse on June 20, 2008 11:56 AM@Daniel Lehmann
If the constructor call fails, the variable will not be assigned and your "Catch" will also fail. You should always call the constructor BEFORE the "Try".
Correct, the constructor will fail and the object will not be instantiated, but you still have access to the variable. So you would have to check if the object was created (check for Nothing) before trying to access any properties or methods, but the variable is at least in the scope of the routine outside of the try block.
Based on some of the comments I've read, it seems you stroke a chord here, Jeff. I, like you, think conciseness goes a long way in code clarity. It is, though, a topic marred by conflicting points (ranging from technical difficulties to personal preferences).
I believe PHP code is a breeze to go through (most of the times, of course -- and provided a decent coder was cognizant of the future pain of his/her successor). Can you honestly say this is not as clear as you can possibly get?
$result = mysql_query($query);
NOTE: I'm not a PHP lover. I'd pick Java any given day. However, you can't deny it is easier, and faster, to read code written in PHP (and, arguably, write) because of this simple fact.
NOTE 2: This comparison also neglects the fact that both languages are very different since they were created to tackle dissimilar problems.
Elvis Montero on June 20, 2008 12:07 PMOne line:
string hash = FormsAuthentication.HashPasswordForStoringInConfigFile(string txt);
Yes, this is built into .NET--and I think it says pretty much everything that needs to be said about this problem. :)
On a side note, the equivalent PHP functions are named md5() and sha1().
WesleyC on June 20, 2008 12:13 PMI'm sure this all so very yawn-inducing for PHP developers.
Mattkins on June 20, 2008 12:19 PMMarcel Popescu:
| var i = 1;
| is i an int, a uint, a long, a short, an int32, int16, int64?
| ---
| It's an int, idiot. Learn your language
Yikes, such venom. The point is: if I'm reading this code which someone else wrote, am *I* sure what was intended? Am *I* sure that the original programmer meant an int? Will "var i" overflow if I change a while loop? Will "var i" overflow if I change an input condition? Yes, the compiler knows. Yes, as I read the code I can examine the right-handside and say "oh, '1' means that 'i' will be an int" but that's much less clear and takes longer than just typing "int" in the first place, especially since that is what the programmer (presumably) intended.
Also, what if it's a expression or a method call on the right-hand side? The insults and calls to "Learn your language" don't help much, then.
@Craptaculus
There's nothing wrong with that in Ruby, Perl, or Haskell
Please, just stop posting, the rest of your post is tripe and retardation but this takes the cake. Ruby and Perl are two dynamically typed languages and have no relevance *whatsoever* in the discussion, and Haskell is more statically typed than C# could ever dream to be with a type system of a richness C# couldn't achieve in a million years.
masklinn on June 20, 2008 12:44 PM
IMHO, and this has probably been said, the simple facts are:
1. "var" (or "auto" or "dim") is a huge time-saver over repeating the variable type in most cases.
2. NOT having "var" (etc) as a signifier of "this is a new variable" means that the simple typo (the #1 flaw in most code which hasn't been sent to a compiler) doesn't get caught by the compiler and results in a very hard-to-find bug. I've worked in a language like this extensively (4th Dimension), and mistyped variable names are a key common programmer error which cause major disturbances.
3. There needs to be a way to declare that you are seeing a particular instance of an object "as" something else (ex, the "BufferedReader" as a simple "Reader") primarily for future code purposes (ex, you know now that it can only be a BufferedReader but in the next sprint you'll be getting the input as a StringReader instead), although also conceivably for current code purposes (it is declared by setting it to a BufferedReader, but you have a conditional right below which resets it to a StringReader if it's a Monday before autumnal equinox); will the compiler be smart enough to cast down to the right level so that all assignments work while keeping all uses working as well?
4. The ability to simply search for "var" (etc) to find all variable declarations is really nice. I too miss that with C and Java.
IMHO, the cure for 3 and 4 is that the cases where auto-classing will NOT work should instead use a syntax like:
var as Reader reader = new BufferedReader ( ... );
Really strange that things long implemented are raising such an interesteed if re-implemented in C# or Java. How about a look at any decent functional programming language?
And well, even with some Oldtimer like Smalltalk one can write
foo := Foo new
.....
I'm sorry but the whole explictly needed static type declaration stuff is so 80ies ;-)
mmmm... syntactic sugar... *gurgling*
Ryan Ische on June 20, 2008 12:59 PMJeff, I like "var"-style type inference (and I'm glad you're posting about programming again), but you dropped the ball at the very end there. Static type inference has nothing to do with dynamic typing. Dynamic typing is bad for the reasons Grandpa Coder listed above (which basically boil down to "dynamic typing means delaying your error-checking until testing and deployment, rather than compile time"), but "var" does not have those problems. It's just syntactic sugar for the same old static type system C# has always had. Which is a good thing.
Of course "var" can be misused and overused. It certainly shouldn't be used in cases like "var i = 42", where it promotes confusion without even saving keystrokes. But it's a great bit of syntactic sugar that can make code more readable, if it's used correctly.
Anonymous Cowherd on June 20, 2008 1:02 PMHmm...
An error occurred:
Rebuild failed: Renaming tempfile 'C:\codinghorror\blog\archives\001136.html.new' failed: Renaming 'C:\codinghorror\blog\archives\001136.html.new' to 'C:\codinghorror\blog\archives\001136.html' failed: Permission denied
Anonymous Cowherd on June 20, 2008 1:06 PMWow masklinn, you still haven't calmed down, and you have the almost magical ability to completely misread what is written. I'm perfectly aware of the nature of those languages, and I fail to see what your comments have to do with what I was talking about (you'll have a witty^H^H^H^H^H rejoinder for that, I'm sure).
Please, just stop posting
Ummm, yeah. How about you just skip reading them instead? You don't seem to have the knack for it anyway.
masklinn -
Is there a reason virtually all your posts have been abusive to people who disagree with your point of view? I enjoy coming to this site, but if the level of discourse is reduced to namecalling, I really don't think I'll bother in the future.
gregs on June 20, 2008 1:09 PMI absolutely disagree - explicitly declaring your type is very important when dealing with object-oriented programming. Example:
class Foo {}
class Bar : Foo {}
var f = new Bar();
f = new Foo();
// this will not compile, since f is typed Bar, not Foo.
When reading code, I much prefer the old-fashioned way.
"var" does have its uses. It's great for the new features of C#, like anonymous types - I'm using it when working with binding a small amount of data to a web page - the data object can be an anonymous type, as long as the property names match up to what's evaluated on the control.
Joe Enos on June 20, 2008 1:45 PMI agree that this neat compile-time trick aids readability of the code. But as several people indicated already, the "var" syntax cannot be used to handle cases where you want to use a base class pointer.
Of course, one can argue that these types of assignments often happen in factories, so in the end there is no problem using the var syntax:
var p1 = Factory.Create("Employee");
where, Factory.Create() has a return type of Person (the superclass of Employee).
Mohammad on June 20, 2008 1:47 PMHave fun with C++ templates
std::vectorstd::basic_stringchar, std::char_traitschar, std::allocatorchar , std::allocatorstd::basic_stringchar,
std::char_traitschar, std::allocatorchar variable = ...
Jeff is trying to reinvent himself as a hardcore C# programamer meanwhile hoping to avoid having to explain his once proud VB roots.
Hoping this is just going to fade into the past I suspect like most C# converts from VB. Jeff, you've got too many pro-VB statements recorded for eternity in this blog for that to happen. You should just buck up and answer everyone who's asked, why you're not just using VB.
Pfff....
I agree, this was a lame post.
VBMan on June 21, 2008 2:37 AMHi Jeff --
Joel explained this very well on the show -- but i don't think you ever quite "got it".
Type inference is not a gateway drug to more dynamically typed languages.
Rather "var" is a gateway drug toward "real" type inferencing, of which var is but a tiny cigarette to the greater crack mountain!
Type inference is used very effectively to create really expressive languages like ML, CAML, and the awesome F#.
These are ultra-static typed languages -- much more static than C#, as the compiler applies much more reasoning about types.
One of the inspirations for ML was a famous paper called "The next 500 languages" which called for the creation of a language called ISWIM, or "If you see what I mean". This proposed a lot of very aggressive type inferencing behaviour in the compiler, and it was embraced by the academic community.
"var" is but a tiny bagettal, a tip of the hat to that world. And hence i see it as a gateway to F#. The Language Of Teh Gods TM !!1!
cheers!
lb
really aggressively and powerfully in languages that are even more static than C#
as others said:
You might even say implicit variable typing is a gateway drug to Hindley-Milner type inference in statically typed languages. ;)
@masklinn is a dick
That's not true at all. I cannot speak for Ruby. But C#, Java, and Groovy CAN catch NullPointerExceptions. It's just that that type of exception is normally the least expected and a try-catch block is not written by the programmer to handle it.
Hey, thanks for proving once again the point I was making in my pair of abrasive posts (out of half a dozen): he was talking about OCaml's *type system* catching NPE (or more precisely making them impossible as the concept of null doesn't exist in the way it exists in Java).
Thanks for playing dude.
you set yourself on a pedestal as coder supreme and treat everyone else as "uneducated retarded inbred morons".
I'm sorry I hurt your feelings and made you aware of your lack of knowledge in CS and computing (which you demonstrated again in this post), but you know... truth hurts sometimes.
@Dani Berg
It just made me wonder how you compared PHP as a mess of functions and how organized is C#.
Simple. Implicit/explicit typing and static/dynamic typing are *completely orthogonal*.
So his point stands in that:
* C#, even with 3.0's type inference, stays *a statically typed language*, which Jeff seems to prefer. PHP is not and has never been statically typed (not that there's anything wrong with that)
* The design of PHP's STD as well as the design of the language itself still blows, that part of PHP hasn't changed.
@TraumaPony
To a person, however, the latter is much clearer.
Not really. It may seem that way when that's all you've ever known though. I guess it's a case of blub
@Friedrich
And well, even with some Oldtimer like Smalltalk one can write
foo := Foo new
.....
I'm sorry but the whole explictly needed static type declaration stuff is so 80ies ;-)
Erm... I may have misunderstood your post but Smalltalk isn't statically typed at all.
masklinn on June 21, 2008 4:29 AMI have to disagree with you here, Jeff.
Say I have a class named Example that implements two interfaces, IFoo and IBar. When I instantiate I have several options when dong so statically.
Example example1 = new Example();
IFoo example2 = new Example();
IBar example3 = new Example();
In the second case I am ensuring that example2 implements a certain interface, and I can swap this out with an instantiation of a different object that implements IFoo. This strategy pattern is fundamental to object oriented programming, and 'getting in the habit of writing code using var' can provide inflexible suboptimal design.
Interested in your thoughts.
If you don't like to type much, you should ditch C# and turn to D programming language.
auto R = new Reader();
And I'd say the "auto" keyword is a mere fraction of D's elegance, power and coolness.
Tomek on June 21, 2008 4:52 AMvar wordCounts = new Dictionarystring, int();
-- YES PLEASE
Dictionarystring, int wordcounts = new();
-- EVEN BETTER
var username = "Filbert";
-- NO THANKS (unnecessarily vague)
var mysteryObject = TheFactory.Create();
-- NO THANKS (requires too much work to find out the type)
This only works for local variables. Since you keep your methods nice and short (don't you?) I think there's really not a lot of scope for confusion. And there *is* value in stripping out redundancy if it can make your methods more concise and readable. I do, however, prefer not to use it such that the type becomes a complete mystery until you look up factory methods.
Weeble on June 21, 2008 6:10 AM@Mike G, et. al. with similar commments...
I find this post very funny considering
that the last entry was "Coding for
Violent Psychopats".
Also, how hard is to write StringBuilder
instead of var on Visual Studio, you
just hit CTRL + SPACE and the IDE does
it for you.
The problem with this "var" keyword is
that while it may sound nice in your
example it is going to be overused and
it will make code maintenance a nightmare.
Exactly what I was thinking!
From one VB convert to another, this really sounds like the VB programmer coming out in you Jeff :)
Fairly strong case of why var may not be the best tool is in your (Jeff's) "Sanitize HTML" post on RefactorMyCode:
http://www.refactormycode.com/codes/333-sanitize-html
The first several comments had valid points in stating they did not implicitly understand what your variable types were for your var's. Sure, RefactorMyCode is not a code review; but, during the refactoring process shouldn't you take into account the code-readability for future maintainers of your code (which brings us right back to your post 2 days ago)?
Kindler Chase on June 21, 2008 6:13 AMOk, after reading everyone's comments here, I guess I will revisit my code and make sure that when I do use var, it is only in places where it is unambiguous.
This is one of the reasons I read your blog, Jeff, the never ending quest to become a better coder.
Thanks Jeff and everyone!
Dennis on June 21, 2008 6:36 AMyou learn something new every day. I totally agree with you I always wondered why you need to specify the type essentially twice. Didn't know this was an option until now. What framework version though as I tend to like to stick with 2 unless I need a feature from a new version.
pete on June 21, 2008 7:28 AMJeff Atwood wrote:
"But why can't the 1 simply grow/size to fit? Wouldn't that be
preferable to the overspecific data typing and the inevitable integer overflow weirdnesses errors and even *exploits* this results in?"
Sounds like a good idea, but I think it might be quite complicated to do in practice. Here's an example:
var x = 255; // It's a byte?
var y = sizeof(x) // 1?
x += 381; // Now it's a two-byte (unsigned) integer, or maybe a four-byte or eight-byte (depending on platform/cpu)?
y = sizeof(x); // 2?
In languages where primary types are not implemented as objects, I can imagine this kind of dynamic behaviour to be rather painful for the compiler/interpreter/virtual machine to keep track of. Also, it would break any assumptions about variable sizes in memory. For low-level stuff you may actually care.
I'm all for reducing redundancy and unwarranted verbosity, but increased ambiguity and complexity may be a high price to pay.
Anders Sandvig on June 21, 2008 8:19 AMCraptaculus:
If you had read my previous post (it was RIGHT above it), then you would know that I agree with you. I was just pointing out that that exact example wasn't exactly a stellar one. A valid one, but a minor one.
More often than not I agree with you Jeff.
I guess when it comes to readability, a more Verbose code is far better more concise code. With readability comes maintainability. Most of the time of developer is spent maintaining the code. While debugging I would like to have Verbose code. But then this is just my personal preference.
I 3 Perl
Steve on June 21, 2008 9:30 AMIf this is the coding style you like, you might enjoy learning ActionScript. Well, AS 2.0 at least. It supports but does not require strict data typing.
Jeremy White on June 21, 2008 9:57 AMagree. even resharper has the same opinion
http://resharper.blogspot.com/2008/03/varification-using-implicitly-typed.html
agree. even resharper has the same opinion
http://resharper.blogspot.com/2008/03/varification-using-implicitly-typed.html
The comments to this entry are closed.
|
|
Traffic Stats |