4 ms·
I have been working with C# for a long time now, so it's pretty cool to watch it become a contender in cross platform server-side development (Mono has been the
by balfirevic 7y ago
I have been working with C# for a long time now, so it's pretty cool to watch it become a contender in cross platform server-side development (Mono has been there for some time now for desktop stuff, but I don't know how much traction it got. I don't think many people used it for back end work).
I think the language is really well-designed. It does have a lot of features, but still feels pretty coherent and not overwhelming. LINQ is great. As for what's coming, I'm particularly excited about the non-nullable types in C# 8.0.
I wish it would get low syntactic overhead sum types, similar to Haskell, OCaml and F#. That's the biggest thing I currently miss.
One thing I am disappointed in is going with async/await paradigm instead of supporting green threads. This essay explains why pretty well, and has already been linked on HN a few times: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
- totalperspectiv 7y agoExcellent article! I hadn't read that in a while and it was a good refresher. I would also prefer going the way of green threads instead. As for typing, I'm coming from C and Python, so the type system has been a fantastic learning experience.
- quickthrower2 7y agoYou can still use threads. You can still stick .Result on the end of an async function to wait for the result,
- rndgermandude 7y agoTo be fair, in C# a function can "opt out" of async-await with Task<T>.Wait()/.Result/.GetAwaiter(). In a way C# will use a mixture of green-ish threads/threads already, in that await-ed calls are either scheduled on a thread worker pool (via a TaskScheduler) or executed synchronously ("inline")... Which comes with it's own set of surprises and gotchas. async Task<bool> DoSomethingElse() { // [0] do something long-running } async Task DoSomething() { var otherTask = DoSomethingElse(); // [1] do something long-running var other = await otherTask; if (other) { // do yet another thing } } So, when will [1] run? Before [0], concurrently on another pool thread to [0], or after [0]? The answer is: you cannot really know from the information presented. The compiler might decide that DoSomethingElse is to be called synchronously ("inline", attached child tasks), so before [1] will get a chance to run. Or it might decide to run it concurrently, but then the TaskScheduler might decide it's doing enough of concurrent work already (e.g. every thread in the pool is busy) and run [1] before [0]. This is usually nothing to be concerned about, until it is. Coming from js' world of async-await where a certain order is guaranteed, I footgunned myself in C#... my real-world DoSomethingElse() essentially was a forever-loop that would only terminate on a CancelationToken (basically a "is this canceled" flag) and the compiler decided it should be executed synchronously for me, so [1] never got a chance to run. The fix was Task.Run(DoSomethingElse) btw, thus explicitly not "inline"-ing the call. https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/attached-and-detached-child-tasks https://docs.microsoft.com/en-us/dotnet/standard/parallel-pr...
- Gibbon1 7y agoI've been using C# off and on since about 2006 or so. Very early on I was a bit dismayed at how hostile Linux users were to the language. Since it has the potential to fill a large gap in the language development space. Most other langues required knowing a bunch of stuff in order to develop, build, and especially allow naive uses to deploy. The various ecosystems had annoying and often perplexing gotchas. With C# all of those were trivial, especially the last one. (Instructions that start with 'download language version x' would be a non starter)