Hacker News new | ask | show | jobs
by alkonaut 4419 days ago
If your language has you type more because it has a static ype system then it's just poor at inferring types and/or it's syntax has you write out things that it could infer anyway. You may have to write types in C# from time to time, but often you don't have to:

// This an array of integers.

var x = new[]{1, 2, 3};

// This is a list of integers.

var y = x.ToList();

// This is an anonymous type.

var pet = new { Age = 10, Name = "Fluffy" };

Zero type names there. Not all types can be inferred by literals though, most annoyingly dictionaries:

var myDict = new Dictionary<string, string>{ { "test", "test" }, { "test2", "test2" } };

although I'm sure that could also have been created without typing out the name if you really wanted.

2 comments

Inferring types is cool, if it doesn't create bugs. But it does. Its not a lot of work to just say it outright, and it can save your life.
Can you elaborate? I'm not sure what you mean.
Unexpected conversions can add bugs. Putting a string into a table that was implicitely integer - if your string doesn't start with digits it gets converted to zero. Was that what you intended? Did you think the table would hold a string?
Type inference in C# with the var keyword doesn't work like a dynamic language like javascript. It works by simply using var as a placeholder for whatever type the right hand side returns, which is determined at compile time.
So the type depends upon the initial values, which might not be representative of your full intent? A list of strings doesn't guarantee you won't want later to put something else in there.

I guess you'd just have to declare it explicitly in that case.

But you could explicitly declare the string table and still try to put an integer into it. Your example isn't an issue of type inference, it's an issue with the developer not properly tracking what variables store what types in his/her own code.
Yep, like if you wanted to put a list behind an IEnumerable interface or something like that, instead of an actual list. It's just a very useful shortcut for the thing you want to do 90% of the time.
Why would you want to put anything other than a string in a list of strings ? That's just looking for trouble IMHO.
So it's not actually the type inference that's the problem -- it's developers who carelessly define implicit conversion operators on their classes.
Strings have built-in conversion, right?
The only built-in implicit conversions in C# are for numerics, and there isn't a loss in precision for those (with the exception of int/uint/long/ulong -> float and long/ulong -> double, where there is a loss of precision).

http://msdn.microsoft.com/en-us/library/y5b434w4.aspx

     int i = "5"; 
would not work.
Not the kind you seem to be thinking of.
Implicit conversions != Type inference
They're doing dictionaries in CS6.
That's sad. They should do tuples and top-level functions and solve it naturally.
They are doing a hack for top-level functions - they're adding "using" for static classes so you can pull all the static methods of a class into the local namespace. Don't see how that would help for dictionaries, though.

The ugly part of the dictionary is the type parameters, but I can't see a workaround for that without some really hard type-inferencing for all generics. I mean, you'd have to infer the type-parameters of a generic class based on the type-parameter of the IEnumerable passed into its constructor (dictionary takes an IEnumerable of KeyValuePairs of TKey, TValue). That's a little messy.

I was alluding to F#'s handling:

  > let myd = dict [ "a", 1; "the", 2; "train", 3 ];;
  val myd : System.Collections.Generic.IDictionary<string,int>

  > let myd = dict [ "a", System.String.IsNullOrEmpty ];;
  val myd : System.Collections.Generic.IDictionary<string,(string -> bool)>
If C# had tuples, then you might be able to do something like:

  var myd = createdict(new[] { {"a", 1} , { "the", 2} ...})
The tuples should get a type inferred, then the array, then that can pass the type to createdict and all good. And the array could be removed if there was some other sort of list-like literal. This might be really difficult to implement in the C# compiler, for all I know.

More likely, they'll graft in yet another special rule in the compiler (not accessible to user code!), just as they did with other collections, foreach, async, etc. I find it ugly that the compiler is happy to use static duck typing when convenient, but such a feature isn't exposed in the language.