Hacker News new | comments | show | ask | jobs | submit login

Definitely agree with you on C#. It feels like this is what a standard, mature, widespread language should be. There are other languages that are better for specific tasks, but for the general programming language, C# really hits the sweet spot in terms of features, expressability, readability, and environment. This is the language that Java should have been--could have been.

Also, I dread getting asked on my next interview "whats the one thing you don't like about your favorite language". I honestly can't think of anything off the top of my head. Granted, I've come across things that were frustrating at various times, but they never stick in my mind. I think that's a testament to how well the language has evolved.

whats the one thing you don't like about your favorite language

That's easy. So many hacker types dismiss you as some sort of weirdo for favoring anything that came from Microsoft.

Or, less glibly, it's a mostly single-platform language with support for other operating systems offered only through third-party tools.

I don't dismiss C# developers, I'm just glad I'm not one anymore.

Do you mind if I ask why? Not being defensive, just curious.

Well, I'm not the gp, but I am a former C# guy who's happy to be out of that world.

1) I dislike C#'s types; they're neither as strong and intelligent as a ML/Haskell language nor as convenient as a Python/Ruby family language.

2) I much prefer the sense of design displayed by Python and Ruby open source projects over C#. (Not that there aren't issues there!)

3) I hate Visual Studio. Nice debugger, crappy interface for writing code. Horrific user interface design for the most part. (At least back when I was writing C# back in 2009!)

4) I hate Windows. Linux and Mac are far more developer friendly. I hated dealing with Cygwin to get some sort of reasonable (crappy but tolerable) command line environment.

5) I love git. Until fairly recently, git was not available and stable on Windows. For it and for many other bits of software, windows is a second class citizen.

Shall I go on? Because I could. But I'll leave it at 5 for now.

As someone who's more than happy with C#, I'm wondering if there's a world out there I'm missing but I can't really connect with what you're saying.

1. "Strong and intelligent"? "Convenient"?

2. "Sense of design"? My current side project includes a web scraper which uses the following open source projects: AutoMapper, CsvHelper, HtmlAgilityPack, Twitter Bootstrap, jQuery, Modernizer, Moq, NLog, MongoDB C# driver, PetaPoco database driver, Rx extensions, knockoutjs and structuremap. 8 of those are .NET specific. Because of their excellent design, I have probably no more than about 30 lines of code hooking up to them (where I use interfaces) and maybe no more than 100 lines of code total utilizing them directly. Yet they conceal YEARS worth of work I would have to do myself.

3. Have you ever used Resharper? I've never heard of anything equivalent on any platform for any IDE (except for IntelliJ, developed by the same company, Jetbrains).

4. I'm fine with Windows. I find both Linux and Mac less developer friendly. I'm fine hosting my services on Linux and interfacing with them from C#, though, because it's a great server operating system. I've been using computers for 20 years and I'm happy to be away from the command line 99% of the time. What do you like about it?

5. Git Extensions + Git Source Control Provider are a completely integrated and free Git experience on Windows.

1. In Haskell and ML, I don't feel like I spend my life Listing<List<T>, X<T>>, and I have type classes. In Python and Ruby, I don't have to specify types. This lets me do all kinds of convenient things.

I don't think it's far out to suggest these sorts of advantages, and I am 100% not interested in rehashing a flame war that's been had a thousand times over. Please allow that these are my judgements, and I hope you don't need to share them to see that many people feel that way.

2. That's nice? I found C# projects to have a poor sense of design. I'm not sure how you expect me to defend an aesthetic decision.

3. I'm glad you like Resharper? I didn't. I'm a vim guy.

4. I'm glad you like Windows? I don't. I see what you mean, as long as you stay in the MS womb, it's a cozy development environment. I tend to like open source software, and it lags behind very seriously in that department.

5. As I said, I last developed C# in 2009, and I thankfully haven't had to touch Windows since. I'm sure git is nice now, but I suspect that Windows is still a second class citizen for many software projects. Git is just the one that annoyed me most back then.

It seems to me that we simply have different aesthetic criteria.

as long as you stay in the MS womb

You don't need to debase an otherwise great conversation with incendiary language like that.

I certainly didn't write it to be incendiary, and I don't read it that way?

I'm not going to go back and edit it, but I'll ask you to give me the benefit of the doubt that I meant it to be as as far from incendiary as possible.

The perhaps unfortunate metaphor the womb implies is that developing in MS tools is like being a defenseless premature baby who needs to be protected from the big bad world until they come to full term and leave the MS environment behind.

To me, this metaphor could be extended to [whatever environment you first really liked]

I am delighted to give you the benefit of the doubt. Thanks for the explanation.

We do and that was my original impression. Yet you listed a number of items even though they all boiled down to the same thing as far as I could tell. Nothing wrong with having different tastes, I just wanted to see if I was missing something deeper in each point.

I stopped at the part where you compared ReSharper to VIM

I'm guessing you like to debug using print and the command prompt as well?

For most the world keeps on spinning, for some it stops in their youth. Sad.

Hell yeah vim rocks!

So too does the command line! high five

> 1. "Strong and intelligent"? "Convenient"?

Not a C# user, but few languages of the strength and intelligence of types in ML. Covariant arrays (which C# presumably adopted for the sake of Java programmers) moves an easy, and obvious, compile time type check to runtime. The type inferencing in C# is very weak relative to ML/Haskell. The type syntax is generally more lighweight in ML/Haskell as well. For example a function that takes a list of some type ('a) and returns the head of the list if it exists or None if it doesn't looks like:

val hd : 'a list -> 'a option

Of course, all if this works in unison with other type functionality that is far more lightweight in ML than C#. The function above is only really so succinct because I have powerful variant types and pattern matching on them. I think they go hand in hand because using an option-type is somewhat useless if I don't have something like pattern matching to access its state.

C# includes the static LINQ method "FirstOrDefault()" for any types implementing IEnumerable, e.g.:

    var firstNumber = numbers.FirstOrDefault();
(This isn't strictly the same as what you described if "None" is different from "null".) Once such a method exists, does it matter how many lines of code it is written in? I posit that every language feature in a reasonably intelligently designed language serves a valuable purpose, and that everybody has different needs, and the verbosity in C# serves certain needs.

Here's an implementation in C# that is a function on types T implementing the IList interface (rather than IEnumerable like LINQ does):

    public static T Head<T>(this IList<T> list) {
      return (list == null || list.Count == 0) ? null : list[0];
It is used in the same way as the FirstOrDefault() example above. Much more verbose, I'll agree! But the real question for this thread is is it less convenient, and if so why? All the verbosity stems from just a few logical places:

1. the 'option' function you have in your example. In reality, your 'option' is doing all the work I did above, which means that comparing the verbosity of your sample code to the C# equivalent of FirstOrDefault() is perfectly valid in my opinion :)

2. the explicit return type. This serves a valuable purpose in my opinion.

With your code, it's easy to break the hd function by changing the implementation to return a different type. You might not even notice the bug if the different type's implementation is close enough to the right one. I once had a bug like this in VB6 years ago: I changed a method to use an integer instead of a string, and VB's automatic type casting happily allowed the rest of my code to function... until in the middle of a demo I ran a function I hadn't tested and default value of 0 broke something expecting an empty string! My lesson: type inference can be dangerous.

It also makes refactoring a large project much more difficult in my opinion because there is no way to distinguish between specification and implementation. Consequently, changing your implementation runs the risk of breaking your specification without being informed.

There is a school of thought that says your unit tests should cover this aspect of the specification... but then all I'm doing is implementing explicit types in a roundabout way - let the compiler do that I say! That being said I don't know if ML/Haskell have 'interface specification' types to ward against this, where you need it (and everywhere else you get to save on verbosity)? That would be a nice improvement to C#: private methods can use extended type inference, anything public (including implementing an interface) need to be more explicit.

3. syntax: visibility (public), static modifier and return statement. This is a matter of personal preference. With Resharper in Visual Studio each of these words costs me 2 or 3 keystrokes, and if I like I can use templated code snippets to reduce that for any situation, so I'm not too bothered :)

I think you're underestimating how much work the type system is doing here: `option` isn't a function. It's part of the return type definition. The whole point of having a type system as strict as ML's or Haskell's is to avoid the sort of problem you had in VB6. Automatic typecasting is a very, very different beast to type inference: in Haskell, your problematic code likely wouldn't have got past the compiler. You're precisely wrong when you say that it's easy to break the hd function by changing the implementation to return a different type. If you do that, your program won't build.

ML's and C# have their strengths and weaknesses, but from a type theory perspective, ML's type system is simply much more powerful when it comes to ensuring correct code than C#'s. Take, for example, your implementation of Head, what if you messed up and wrote:

> return (list.Count == 0) ? null : list[0];

Would the C# compiler catch it or would you not find out until runtime? An ML compiler would tell you that function is wrong.

What about using Head? If you have a list of integers, will the compiler let you do:

> Head(integer_list) + 2

An ML compiler won't, because it's not safe.

> This isn't strictly the same as what you described if "None" is different from "null".

It is, but the important thing to note is I had to specify that the function, 'hd', can return 'null', by wrapping it in the option type. 'null' is only a valid value for option types. If I write:

> val hd : 'a list -> 'a

I could not return 'null'/None, it simply isn't valid. And the compiler wouldn't let me.

> the 'option' function you have in your example

'option' is a type, not a function (I suppose you can make some high level argument that all types are functions over values or something, but not relevant here). And 'option' itself isn't really even a type, it requires a type variable, so "'a option" is a type where "'a" is replaced by a concrete type at some point. It's not doing the work you described above, it's actually defining a contract between me and users of hd and the compiler.

> With your code, it's easy to break the hd function by changing the implementation to return a different type. You might not even notice the bug if the different type's implementation is close enough to the right one.

No, it isn't actually. If I change the return type the compiler will not compile my code.

> I changed a method to use an integer instead of a string

This cannot happen in ML, the compiler won't compile it because an integer isn't a string. What you described is not type inference, it's dynamic typing. The only danger of type inferencing in ML is annoying type errors during compilation. I'm not sure you actually grok what type inferencing is.

> It also makes refactoring a large project much more difficult in my opinion because there is no way to distinguish between specification and implementation. Consequently, changing your implementation runs the risk of breaking your specification without being informed.

Actually, refactoring code in ML tends to be pretty easy. If you change the type of something the compiler won't compile your code, so you know instantly where you messed up and can fix it. You can construct code to make this not work, but in general that isn't the case. See https://ocaml.janestreet.com/?q=node/101

> let the compiler do that I say!

Exactly, and an ML compiler definitely does more of this than the C# compiler. At a cost, of course.

Your post has several statements which suggest you are ignorant of ML and type theory. If you're interested in learning more, check out Benjamin Pierce's book "Types and Programming Languages". Or just spend a weekend with Ocaml or Haskell and prepare for the compiler to frustrate you with it's strictness :)

As far as #4 is concerned, windows is not configurable and the "command line" is an absolute joke, which renders the idea that it has a better developer experience absolute rubbish :) The command line is super powerful and highly convenient in a developers hands.

The lack of configurability is a bug or a feature, depending on your purpose and your disposition. I personally can't stand configuration nightmares. I want things to just work as much as possible, and in my experience linux has a real problem with that. I'm a programmer, not a configuration engineer. I expect the systems I use to understand that.

PowerShell is no joke. Even if you never intend to use Windows again, it's worth taking a look at, there are some interesting ideas in there.

(Overall though, I agree that Linux and Mac give a better developer experience.)

Seeing as how I've been developing for the last 15 years on Windows and haven't found the lack of a *nixy command line to be an issue I'd love to know what you're doing that I'm not :)

Well, the command line basically means you have the power of a full programmming language at your fingertips for administrating your system, your projects, your build system, etc.

Also, the homogeneity of the unix interface (pipes and utilities that uses them) means that you also have very powerful primitives to work with.

Proving the utility of the command line could benefit from a few full featured examples, but this would need a longer post that i'm in the mood of writing right now :)

With that said, you have a powerful administration programming language on windows called powershell. It's much better than bash by a lot of metrics. The way it's integrated into the system is not very good though. For example, the terminal client sucks, and the security system is way too complicated for casual use.

I Spend a lot time in the command line on Windows. Powershell, GnuUtils, and the Windows server resource kit make it much less of a joke than it used to be.

The only way to know if there is a world out there that you're missing is to go explore it. The biggest problem with the .NET world is that the vast majority of .NET developers have spent the vast majority of their time in it.

Same boat, but still wrestling with windows at work. I've got a workable configuration with Cygwin, and mingw32. Hey Visual Studio's IDE (2008) may be full of cruft but the debugger isn't too bad. Vs2010 feels broken, I gave up creating projects in VS, and now use a simple combination of ruby and cmake for creating solutions/projects.


Thanks for the thoughtful reply. I've absolutely felt your pain. Some of those things have maybe improved (I use git every day, I love my PowerShell, and Visual Studio + ReSharper is glorious once you tell some of the cruft to stay out of your way) but it's still a long way from perfect.

It's amazing how many people either dismiss PowerShell out of hand because it's different, or don't even think about it when talking about Windows commandline support. Getting .NET objects returned, rather than piping text around is awesome. So is having an IDE specifically for writing PowerShell scripts. I'm still learning PowerShell, and love bash, but as powerful as bash is, in some ways it feels very primitive in comparison. If PowerShell 15 years old when bash was released, would anyone consider it better than PowerShell?

Powershell did not exist when I was a C# programmer. Not saying it would have made a difference either way, just that I couldn't have mentioned it.

Anyway, I don't think bash/zsh is so great, rather the tools that have grown around them for the last 20 years make them the best available option. Powershell may be nice, but it's got a long road to hoe.


It has a steep learning curve, as one needs to learn a new set of commands, but once you start getting it, it is great.

I just have two complaints with it: - the stupid ps1 extension; - commands are verbose when comparing with other shells

Agreed that PowerShell really does make command line work on Windows much more pleasant than the old DOS prompt. I just discovered a PowerShell module for working with Git (https://github.com/dahlbyk/posh-git). It shows status info right in your prompt line and does tab completion of git commands and branches.

Crazy. I could have (honestly) written this exact same post, timeline and all.

4) Powershell! Sweet mother of Scripting Gods, Powershell! As a language it's what Bash should have been. Bash is better in some usability senses like tab completion, but Powershell operates with pipelines of .NET objects instead of pipelines of text.

C# programmer for a couple years, and I think C# is OK (it's definitely way ahead of Java or C++) but I've definitely got a big list of things I don't like about it. The top of it reads:

- Events and properties aren't first-class, which is lame. I can't even easily get the "get" or "set" method of a property without either using reflection or making a wrapper lambda.

- No syntax sugar for tuples.

- No syntax sugar for destructuring anything. Come on now.

- The type system has big holes. For example, I still can't specify class Something<T> where T : new(T) (i.e. where a copy constructor exists on T.) And I can't specify class Something<T> where T : /* is a numeric type */.

- It would be nice if there were type inference on more things, like property and field types.

- All reference types are nullable which sucks.

This is a good list. The lack of decent sugar for tuples makes them very annoying to work with and situations demanding two or more dependent return values are the one place where my code looks nasty and is difficult to follow (unless I create a class specifically for the return type, which I usually end up doing).

By numeric type do you mean a type implementing numeric operations? I agree, it's weird they haven't just whacked an interface on that.

And when are we getting an "unless"? It's way more readable than "if (!(some complex condition))".

Oh and null coalescing with member support. "y = x != null ? x.prop : value" is way too verbose.

> The lack of decent sugar for tuples makes them very annoying to work with and situations demanding two or more dependent return values are the one place where my code looks nasty and is difficult to follow (unless I create a class specifically for the return type, which I usually end up doing).

At least you have the option of out params. I have to use Java every day and the only real option is return classes.

I don't know if I misunderstanding you, but you can indeed specify class Something<T> where T : new Check this out: http://msdn.microsoft.com/en-us/library/d5x73970.aspx

And about numerical types, I agree that would be great to have a base class "Number" for double, int, etc. But meanwhile you can use this trick: http://stackoverflow.com/questions/3329576/generic-constrain...

Right now you can only specify that a type must have a paramerterless public constructor. He or she wants to be a le to specify (presumably) arbitrary constructors (or at least a copy constructor).

Most of your issues are addressed by the Base Class Library (BCL), which is provided by the runtime itself. You cannot use C# without the BCL, so why evaluate it without the BCL? How do the following sit with you?

- Events, i.e. the observer pattern, are indeed supported first class by way of the `event` keyword and BCL `Delegate` type. And the whole point of properties is to be syntactic sugar to hide implementation details by surfacing state accessors with field-like mechanics. If you need a quick and easy way to reference a "getter method", you're breaking the abstraction and shouldn't use properties. That's the trade off.

- The BCL provides multiple generic, high-performance `Tuple` types.

- Destructing. Memory management is handled by the GC, so what would destructing even mean? The `using` keyword along with BCL type `IDisposable` provides a very usable mechanism for releasing non-memory/unmanaged/OS resources.

- This is mostly valid. That said, `ICloneable` can get you most of the way w.r.t. the copy ctor. As far as the numeric generic, one is required to make do with type-specificity and method overrides, since the numeric types were written without generics in mind. Or you can implement your own numeric type system. Do that once and you can write numeric generics to your heart's desire.

- How could this work with auto-properties?

- Trivial to implement a `NonNull<T> where T : class`. But because of other language constructs (`??` operator) idiomatically `null` references are not considered the end of the world. Design by contract support in the BCL `Contract` type alleviates this as well.

edit: expanded property method explanation.

He said destructuring, not destructing. Like so:

   int a, b;
   (a, b) = function_returning_array();

Regarding events: It's a common pattern to pass a function into a method as a callback to do an inversion-of-control kind of thing, like "on error, call this." It would be natural to pass an event with the semantics "on error, fire this event." But there is no way to pass an event. You can imagine similar situations with properties.

A good list, which can be extended. Just recently, for example, I came across the unpleasant fact that interfaces in C# cannot be nested (in fact, a C# interface is not allowed to define any nested types). Inconvenient, breaks encapsulation, and does not seem to have a good technical reason for it.

And yet, working with C# is joyful.

Your list basically boils down to "C# isn't <insert favorite language>". Which is fair of course, but most of your list wouldn't really make sense in C#.

That's just not true.

All the suggestions on the list make sense, and many like them have been added over teh past few years. To me it seems that all of them except the 'reference types that are not nullable' one could be easily added without breaking backward compatibility.

In fact, I wouldn't be amazed if a C# 6 has sugar for tuples and destructuring assignments and the likes. It matches the language well (already got a type-inferencing compiler, already on the road to incorporating increasingly many functional programming ideas).

And, well, in code you can already say

    var george = new Person();
But in property and field definitions, you still have to say

    Person george = new Person();
How is allowing "var" there a turning "C# into a different language"? Nearly the entire list the GP mentions are fixes on this level of complexity.

The only reason I see for not doing things like this is to avoid becoming the next C++, in which there's just too many features and things to understand.

What you suggest could work, but I'm not sure how useful that would be in the end when you still have to declare the type for fields initialized in the constructor. The var keyword inside methods covers most cases of using variables. A "var" keyword on the field level would cover less than half of the cases. Plus, you'd have to add a new keyword to do it as "variable" doesn't quite fit the meaning. Just not sure how useful that is.

sugared tuples and destructuring doesn't really fit. You'd have to make special case syntax for it and it would just feel bolted on to the language. Plus, tuples lose their usefulness if you have to declare its type to pass it between methods.

Though his first point about getters and setters does make sense, I didn't quite comprehend it the first time around.

You'd have to make special case syntax for it and it would just feel bolted on to the language. Plus, tuples lose their usefulness if you have to declare its type to pass it between methods.

I think it could be OK even without return type inference on methods. Imagine you could type this:

  (int, bool) TryParse(string str) {
     // do stuff
     return (num, success);
That would be clean enough.

I think you might be right about that one. That does look rather elegant. I was initially skeptical about creating a totally new language construct to create inline tuples, as (num, success) looks like it needs a new in front of it, which ruins the pattern of assignment for destructuring.

But once you get over that mental hump of seeing a new in front, it really starts to make a lot of sense. A tuple could be considered a value type and treated similarly to int or string literals. Very cool.

How would you access the return value object? Given obj is (int, bool), obj.Key and obj.Value? Or obj[0] and obj[1]?

Why would sugared destructuring not make sense in C#? Or first class events and delegates?

Destructuring just doesn't fit with the current language syntax. There are no copy constructors in C#, so something like [a, [b, c]] = [1, [2, 3]] makes no sense syntactically. In languages where declaring objects don't require a new, this syntax follows naturally.

For the simple case of say, destructuring a tuple, that could work well: a, b = ReturnsATuple(). But anything more general would just seem tacked onto the language.

But then again, tuples don't really fit well in C# either! Tuples are only useful if you don't have to declare their types, ever. Without full type inference, nothing is saved by using tuples over, say, an inline object.

I don't understand the significance of first class events, so I can't really comment on that. And as far as I know, delegates are first class now with the inclusion of lambdas.

Did you have a look at Scala?

- There are only properties, no fields or other stuff. This means you can replace a method with a constant easily, or add your own setter to a mutable property later without breaking source or binary compatibility.

- Tuples: (1, "Foo", 42.0)

- val (a,b) = (1,2). Also works with regexes, case classes, ... basically everything which has an `unapply` method.

- class Something[T : Numeric]

- Type inference everywhere, with the exception of method parameters (and recursive methods).

It also has one of the most powerful type systems, traits, everything-is-an-object, higher-order functions, higher-kinded types.

Caveat: Runs on the JVM. The .Net port hasn't been officially released, but is planned for the next release.

There is an introduction for C# developers, if you are interested: http://docs.scala-lang.org/tutorials/scala-for-csharp-progra...

That is easy -- non nullable objects. What I mean by that is that you can already specify that some numbers may be nullable. I would love to be able to specify that some objects cannot be null and have the type-checker verify it.

Even better I would have an option type so that you never need to use null, ever.

They don't really work at the type system level, but Code Contracts (http://msdn.microsoft.com/en-us/devlabs/dd491992), though quite verbose, may be used to achieve that to a certain degree. The integration with Visual Studio is decent and the documentation is great, but they are designed to provide a whole design-by-contract framework which may be an overkill.

That's a good one, I'll keep that in mind. (I'm not just cribbing, I ran into a real world situation that just screamed non-nullable objects).

I remember Anders saying that that was one of his regrets for not implementing this from the beginning. According to him adding this now would break quite a few things, but he hasn't yet given up on the idea.

I agree in large, but there are some rough edges.

-It's wordy. The var keyword was a step in the right direction, but there's still a lot of redundant type information, even compared to other statically typed languages like Go or F#.

-Legacy code. A lot of things that are concise and easy in C# 3.5+ were possible but hideous in older versions. Sadly, that code must still be maintained.

-Null handling. Like another commenter, I wish the language would help more with null values. I'd love an operator to do monadic null coalescing: var foo = thing1.thing2.thing3.bar; Sometimes I want foo to be null if any of the chained objects are null.

It's a pretty good language, though. I'm looking forward to the Roslyn API to the compiler: http://msdn.microsoft.com/en-us/hh500769

Legacy code is a problem in every language. Whether the language evolves, or just the common insights of how to use it best.

In fact, C# deals excellently with legacy code. While, unlike the JVM, .NET is not binary backward compatible (allowing some excellent language improvements that Java still has not managed to pull off), it is nearly (but not entirely) source code backward compatible. Sure, this allows to old code using old constructs to stay alive, but it works. That alone is pretty unique, especially if you see that nearly any other language either does not manage to move its community to the next version with breaking changes (Python 3, PHP 6) or has tons of compatibility issues every time something changes (Ruby, Scala), or simply is at a standstill (Java).

Having to deal with a DictionaryBase child class which was made before generics were added is way less of a deal than not being able to upgrade your software to the newest version of the language at all. Which is what would've happened if this was done like Scala. Or, if it was done like Java, we'd still be hacking DictionaryBase child classes.

I'd maintain that no language/platform deals with legacy code better than C#.

Good point. Having to deal with portions of old code is better than not being able to use new features at all. I've revised my opinion.

FYI, Python has an automated script for migrating code from Python 2.x to Python 3.x

You should tell Django guys they should be thrilled to hear it.

Django already has a branch with support for Python 3.x. The only reason why they're holding off on deprecating older versions is so that users get enough time to upgrade their systems.

A lot of hosting environments like Google AppEngine still do not support Python 3. The "there's going to be no 2.8" PEP might help that, though. We can only hope.

I found it half funny that Python 3.3 reintroduced the unicode string literal for Django. The only way support will come is if user push their providers to get up to speed. It is such a pain that Python has become forked for all practical purposes.

Here's an interesting blog from the Django developers about their plans for python 3: https://www.djangoproject.com/weblog/2012/mar/13/py3k/ The short of it is that they are planning to move for sure and with each release of Django they drop support for one of the 2.x releases of python. Django 1.5 (the next major version) will experimentally support python 3.

I was being facetious - my point is 2to3 has been around since py3 was released and Django was python 2.x only for years, along with many other libraries, implying that porting is a bit more involved than applying a script :)

I don't understand the points about Scala here. Scala has pretty much the same strategy as C#.

In fact, the "big breakage" in Scala everyone loves to cite was the addition of better collections. Just like C# did in 2.0 and now finally drops the old non-generic ones with WinRT/Metro.

The reason it gets so much flack is that Java developers want _binary compatibility_, because that's what they are accustomed to and Scala gets often used by Java developers. Java developers would target the same criticism towards C# if it would run on the JVM.

Hm, hm. I guess you're right. Or, at least, I can't find any proof that you're not, so you get my benefit of the doubt :-)

I take the part on Scala back.

No problem. :-) If you have any questions, just ask.

Null handling

You can do a fair amount of relatively frictionless null handling with extension methods. If that helps.

var foo = thing1 ?? thing2 ?? thing3 ?? bar;

This will work.

"thing1 ?? thing2 ?? thing3 ?? bar" will return the value of the first non-null variable in the list. zmj wants something like Ruby's andand [1] instead.

andand negates the need for an explicit null check on each property in a property lookup chain, which would normally be required to avoid a potential NoMethodError or NullReferenceException.

You can create something similar [2] to andand in C# if you are willing to do property lookups using lambda expressions.

[1] http://andand.rubyforge.org/

[2] http://stackoverflow.com/a/4958550

Yep. To me C# feels like the standout all-round language. It's not super-elegant, but it's modern and brings together a lot of useful features without messing up much. I especially like the stuff that was added in v3.0.

On design alone, I would probably vote Clojure. The features and their rationale are very compelling.

<i>I honestly can't think of anything off the top of my head.</i>

Limited support in the open source ecosystem? Open source projects are reluctant to build on something that might infringe on an MS patent. That's what keeps me away from the language. To be fair, this is more an indictment of the patent system than C# itself.

I was thinking more along the lines of the language itself. Complaints about the (lack of) open source ecosystem are more than valid. That's something I dearly miss in the .Net world.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact