15 ms·
C# is a pretty underrated language. I've worked with JS, Java, C++, Perl and I've always preferred to use C# for personal projects. async/await - C# is the ONL
by me551ah 8y ago
C# is a pretty underrated language. I've worked with JS, Java, C++, Perl and I've always preferred to use C# for personal projects.
async/await - C# is the ONLY language which gets this right. Javascript has it now but you need to be use libraries which support it too, which are hard to find. Kotlin has coroutines but Java base library doesn't have support for coroutines so you can't use it all the way through and create a chain of all async functions. Once you use async/await it's hard to go back, since the code is as easy to write as synchronous code.
Then you have proper support for generics(unlike Java which has type erasure), LINQ queries and an amazing IDE which is visual studio.
- mr_toad 8y agoI’ve always liked C#. But official support outside Windows is only very recent. And .NET is still very much Microsoft’s baby. Unlike an independent language like C or JS or Rust, MS could pull the rug out at any time. Yes, Mono. But Mono is an unofficial port of a moving target. They have no control over the direction of .NET.
- benaadams 8y ago.NET Foundation's baby now https://dotnetfoundation.org/ https://dotnetfoundation.org/ With open membership https://dotnetfoundation.org/blog/2018/12/04/announcing-net-foundation-open-membership https://dotnetfoundation.org/blog/2018/12/04/announcing-net-... and election of its board https://dotnetfoundation.org/blog/2019/01/23/why-you-should-join-part-3-become-a-board-member https://dotnetfoundation.org/blog/2019/01/23/why-you-should-...
- mr_toad 8y agoThe board hasn’t even been elected yet! Maybe MS will in future cede all control over the language. Maybe in future 99% of code contributions won’t come from Microsoft employees. But even then it would take years for the language to become more widely adopted outside Windows.
- mandeepj 8y ago> MS could pull the rug out at any time. What you mean? C# is open source. And, here is the location - https://github.com/dotnet/csharplang https://github.com/dotnet/csharplang
- kevingadd 8y agoA considerable portion of Mono's original developers & current maintainers are on Microsoft's payroll and have been since the acquisition of Xamarin years ago. Because large portions of .NET and C# stewardship moved over to the .NET foundation, community members have a formal role in the development of both as well. So in practice, 'pulling the rug out from under' Mono (or .NET Core) users would be pulling the rug out from under paying customers.
- VRay 8y agoWell, surely Microsoft wouldn't randomly pull the rug out from under a small subset of its own customers! Unrelated, anyone know how I can get my Windows 10 Mobile phone to sync Zune songs to my Windows Media Center? My Xbox360 stopped working smoothly after the last few forced updates
- shijie 8y agoHave you used Golang or Elixir? These languages get it very right.
- me551ah 8y agoGolang is pretty interesting, given how it's architected. But you have the concept of channels added on top of async/await which you need to keep in mind.
- Rusky 8y agoThey get something else right, not async/await. That something can often be used for the same purpose, but it's a different tool.
- weberc2 8y agoHow is this not a difference without a distinction?
- daeken 8y agoI can drive in a nail with a hammer or a boot, but that doesn't make hammers and boots the same thing. There are many different ways to accomplish any task.
- weberc2 8y agoI don’t think your analogy is very good. Boots are useful besides driving nails. What is async/await useful for except concurrency?
- da_chicken 8y agoI have no experience with Go, but boots being useful at tasks other than driving nails was pretty clearly exactly their point.
- 8y ago
- nicoburns 8y agoI think C# is underrated because it was closed source for so long, and working with a closed source ecosystem is such a pain (and risky!). At least personally, that made C# a complete non-starter for me before. However, I've recently started learning it, and it really is nice. It's much more pleasant to work with than Java. Hopefully it will see a renaissance when people realise that with ASP.Net Core they can write code that looks broadly similar to Rails/Laravel/Django code, and get much better performance more or less for free. There are definitely some rough edges around the ecosystem though. Entity Framework isn't nearly nice as Laravel's Eloquent ORM, and it's pretty jarring looking at a promising library, only to realise that it's a commercial offering (don't get that with PHP!).
- cbHXBY1D 8y agoNot to mention the recent performance gains from adding Span<T> in .NET Core 2.1. I've used F# in a few professional projects before and that language is certainly underrated. I used to work in Microsoft's DevDiv and everyone knew it was criminally underfunded. I think if it had OCaml-style modules and Microsoft threw more weight behind it could take off big time.
- nicoburns 8y agoIndeed, it was learning Rust that led me to being interested in learning C#, and Span<T> is basically the equivalent of Rust's &[T] slices, which are super useful for avoiding copies. It's pretty cool that C# has things like these and stack-allocated structs, which let me carry over a lot of the performance optimizations I might use in Rust.
- platz 8y agoDon Syme will never allow ocaml-style modules
- Scramblejams 8y agoWhy not?
- hiciu 8y ago> async/await - C# is the ONLY language which gets this right Have you tried Python's asyncio?
- deleted 8y ago[deleted]
- roganartu 8y ago> Javascript has it now but you need to be use libraries which support it too This applies just as much to Python asyncio so I'm not sure it's a good suggestion from that perspective. You can use an executor to wrap things that don't support asyncio but that doesn't really qualify as good asyncio/await imo.
- nicoburns 8y agoYes, although it also applies to C#... so it doesn't actually make much sense as a criticism. Although I guess maybe there was a point in time where Node libraries hadn't all transitioned to Promises yet.
- lkschubert8 8y agoI still see a fair amount of node libraries that either haven't converted to promises, or their documentation makes it unclear if a function with a callback has a promise based alternative.
- kahoon 8y agoTypeScript supports async/await pretty well (after transpilation of course).
- nick_ 8y agoThe golden touch of Anders Hejlsberg :)
- vedantroy 8y agoI'm not sure why people (were) downvoting the parent comment. Typescript (and normal Javascript) both support async/await very well as long as you use Babel to compile your code. Infact, you don't even need to use Babel to compile your code because a large portion of browsers natively support async/await: https://caniuse.com/#search=async https://caniuse.com/#search=async I'm not sure why people say you need libraries that support async/await. In JS/TS, async/await are built into the language itself and most libraries utilize the Promise API, which means they also support async/await (since async/await is built on top of promises).
- kahoon 8y agoAnd the TypeScript compiler is now capable of generating the polyfills too, so you don't even need Babel for that: https://bit.ly/2UlW9hs https://bit.ly/2UlW9hs Example taken from here: https://mariusschulz.com/blog/typescript-2-1-async-await-for-es3-es5 https://mariusschulz.com/blog/typescript-2-1-async-await-for...
- rpeden 8y agoI love C#, but I also don't find async and await in JS to be too bad. It's easy enough to wrap a non async library with promises so I can use it with async and await. I've sometimes done the same thing with non-async libraries in C# by wrapping them with Tasks.
- dhd415 8y agoWrapping a sync method in a Task causes a thread to block on the sync method's completion and blocking threads is much of what async/await is intended to alleviate.
- whoisthemachine 8y agoI'd be inclined to believe he means wrapping an asynchronous method (with callbacks) in a Task.
- manigandham 8y agoWrapping non-async code with a Task doesn't do anything. It's only useful if you need to pass a Task around instead, or need to move that work to a different thread. Otherwise you might as well block in the method you're already executing instead of adding more overhead.
- int_19h 8y agoI think they meant wrapping it so that it runs in a background thread, e.g. with Task.Run.
- rpeden 8y agoYou're absolutely right! It doesn't make sense to do this most of the time. I wrote my original message in a rush and left out a lot of context. I usually only do this when I'm pretty sure I'll have to farm out the functionality to a separate service in the very near future. I just start with an async facade around the library, and then swap in an async wrapper around the web service when the time comes. Then I can just drop it in without needing to make any changes aside from changing the interface binding in the DI container initialization. I suppose this might violate YAGNI. But I really don't do it often at all. I only doing it when I'm following the principle of PSIGNIS (Pretty sure I'm going to need it soon). Maybe it's better to just use the library synchronously and then refactor when it's time to move the functionality to a separate service. I don't think the amount of dev time spent is hugely different either way.
- PerfectElement 8y agoI think it's only underrated in the HN/startup world.
- snorremd 8y agoYeah. My impression is that C# rules the world of enterprise and fintech software, at least here in Norway. It might be different elsewhere. It seems like a good language with very good tooling if object oriented programming (in the Java and C# sense) is your posion of choice. Now with .Net Core and other good iniatives from Microsoft it might be a more relevant language than ever.
- dmarlow 8y agoThe are startups using it. We're just not in the MS bashing bandwagon you see here on hn.
- bauerd 8y agoI don't get the impression that C# is bashed on HN, rather the opposite
- vezycash 8y agoThey said "MS bashing" not C# bashing. In other words, using anything MS was once considered uncool. There's still a number of people who are waiting to catch MS pull a Embrace... stunt. I've not seen any thread on HN bashing MS without reason. However, the only guys who claim to use C# either work with big companies or freelance.
- NicoJuicy 8y agoMS basshing was only based on the M$ quote. Because it was closed source. Some context has shifted, the Microsoft takes over Github part has shown sentiment shift also ( not everyone of course)
- 8y ago
- pjmlp 8y agoIt depends on whose circles one moves around. Since I have mostly been around enterprises, I can say it is pretty much appreciated. This are however the kind of customers that will happily have WebSphere, SAP, cluster management with AD, SQL Server OLAP and so on. There won't be any projects being published on github and getting software into the projects always requires some kind of change request. Not the kind of shop many HNers like to talk about. Regarding Java, as someone that works on both platforms, I still look forward that Valhalla comes to fruition.
- hestefisk 8y agoThose shops that you talk about are typically large banks and / or insurers where change requests processes are put in for a reason. Cost of an error can cost millions of $s.
- pjmlp 8y agoNot only, and I do agree with those change requests. Which is why I am usually against the "I rewrote X in Y", unless it holds a good business value story going for it.
- snorremd 8y agoMy anecdotal feeling is that most popular JavaScript libraries expose promise-returning functions these days. Browsers and Node has supported Promises for about four years, and async/await has been around for about two years. I have not personally had much problem using async/await with third party libraries. And wrapping those that use good old callbacks was pretty easy all things considered.
- rienbdj 8y agoNonsense. F# has a better async story. Javascript is also good.
- strmpnk 8y agoAfter dealing with F#'s Async<T> in production, I'm not sure I'd prefer it to the TPL. There are plenty of performance and efficiency problems and the expressiveness is also a double edged sword (we found lots of programmers had issues getting a good intuition around evaluation vs definition time and even very experienced F# devs would get surprised). Part of it is not necessarily the design F# took but that the TPL is incompatible enough that the mixing of TPL-centric .Net libraries becomes a problem. It might be wise for F# to support the TPL via computation expressions with something like `task { ... }` (there are a few implementations out there but a compiler supported state machine generator would be more ideal).
- sparkie 8y agoThere's a `task {}` computation expression is the FSharpx.Extras library, which makes it much more pleasant to work with TPL libraries, and removes the performance issues associated with using Async.AwaitTask etc.
- strmpnk 8y agoYes. That one works pretty well, though it still lags a bit behind the efficient state machines that C# generates which can also help avoid a lot of allocations and indirection in deep task chains. One step at a time though, it'd be great to see F# get a refresh around the TPL (even though it had Async first, it'd be better to align with the platform in the long run).
- platz 8y agoThis is the most current one https://github.com/rspeele/TaskBuilder.fs https://github.com/rspeele/TaskBuilder.fs that Giraffe also uses.
- 8y ago
- deleted 8y ago[deleted]
- weberc2 8y ago> Once you use async/await it's hard to go back, since the code is as easy to write as synchronous code. Wait until you try goroutines :)
- zzzcpan 8y agoI don't think anyone would enjoy going back to goroutines (threads) after async/await. Multithreaded code is actually much harder to write and deal with. Go is inappropriate example here.
- WoodenChair 8y agoGoroutines are not threads: https://rcoh.me/posts/why-you-can-have-a-million-go-routines-but-only-1000-java-threads/ https://rcoh.me/posts/why-you-can-have-a-million-go-routines...
- zzzcpan 8y agohttps://en.wikipedia.org/wiki/Thread_(computing)#M:N_(hybrid_threading) https://en.wikipedia.org/wiki/Thread_(computing)#M:N_(hybrid...
- giancarlostoro 8y agoGoroutines are probably closer to Fibers which D also has: https://en.wikipedia.org/wiki/Fiber_(computer_science) https://en.wikipedia.org/wiki/Fiber_(computer_science)
- zzzcpan 8y agoThey used to be closer to fibers years ago, when they were running on a single thread by default. Now they behave exactly like normal threads with the same problems. And fibers are threads anyway.
- 8y ago
- hacker_9 8y agoUnderrated? Do you live under a rock by chance?
- deleted 8y ago[deleted]
- jenscow 8y agoI've used C# since 1.2 (not exclusively). The language is really good - it's one of my favourites. It's almost 2 decades old, but it's evolved naturally and is still a modern language. Unfortunately, it's the shit around it that let it down... MSBuild, NuGet, VS - they're full featured, but very slow and clunky and hard to work with. Only popular because there's been no viable alternative. Now, with dotnet core, there's no more reliance on Windows (for both dev and production). I can develop and deploy on my preferred OS, and there's a choice of IDE (Rider and VS Code).
- PerfectElement 8y agoI use Rider for a pre dotnet core large project and it's much faster than VS. It's like having VS with Resharper, but without the performance hit that Resharper brings.
- jenscow 8y agoYes, I find Rider to be like ReSharper without VS.
- moogly 8y agoA lot of people in the C# community actually use Paket (F#'s package manager) because NuGet is a complete shit-show. I'm about to do that change myself, because NuGet is truly one of the worst package managers I've ever used (and that is saying something).
- brianberns 8y agoI’m an F# developer in a C# shop, so I’ve only used NuGet. Can you enumerate some of the advantages of Paket?
- chusk3 8y agoparaphrasing from the main site(https://fsprojects.github.io/Paket/ https://fsprojects.github.io/Paket/): > Paket is a dependency manager for .NET and mono projects, which is designed to work well with NuGet packages and also enables referencing files directly from Git repositories or any HTTP resource. It enables precise and predictable control over what packages the projects within your application reference. The big change is solution-level dependency management instead of the nuget-default project-level management, so you always have the same versions of dependencies across all projects in a solution. It also uses a lockfile for these versions so that restores are idempotent. It also allows for fetching independent files from HTTP-accessible locations or git repos, which is nice in F# because the language is succinct and enables you to reuse modules without going through the rigamarole of making and publishing nuget packages.
- tehlike 8y agoC# and typescript if you wanna stay in nodejs. Microsoft knows how to develop a platform.
- nqzero 8y agoasync/await is available in java via kilim (i'm a maintainer) and quasar (though that project is on hold while the author works on project loom) https://github.com/kilim/kilim https://github.com/kilim/kilim
- qaq 8y ago? in JS you can promisify cb style lib you can await any function that returns a promise so why do you have to use libs that support it ?
- CuriousSkeptic 8y agoDon’t underestimate erasure. Theories for free is a useful thing. Granted c# generics allow for some useful meta-programming not possible in Java. But I’d rather take a language with no runtime reflection at all and a properly staged metaprogrammimg instead
- tigershark 8y agoBeing forced to pass the type as a parameter in a generic java method is pretty annoying... and it has nothing to do with metaprogramming, a simple generic factory method or even an “IfNotNull” generic function would need it.
- CuriousSkeptic 8y agoBut that’s type inference. Haven’t touched java since version 7 i think. But was pretty convinced they both have comparable type inference capabilities when it comes to parametric polymorphism. The big difference between C# and java is the reification of the parameter values, inferred or not. And the reification method choosen for C# gives you some extra metaprogramming capabilities, especially when combined with reflection. My argument was that this can be provided design time instead (inference too) while retaining the extra safety of having theorems for free
- naasking 8y ago> Don’t underestimate erasure. Theories for free is a useful thing. Indeed, phantom types are wildly underappreciated. Long ago, I created an library [1] that ensures the type safety of any runtime generated programs you create using it. It does this by typing the various stacks that are in play at any given time, but every new generic type on the CLR ends up creating new type descriptors in global data structures (which aren't GC'd), so complex programs with deep stacks end up generating a lot of static, uncollectable data that just hangs around forever. [1] http://higherlogics.blogspot.com/2008/11/embedded-stack-language-for-net.html http://higherlogics.blogspot.com/2008/11/embedded-stack-lang...
- tapirl 8y agoComparing to what? It may be underrated comparing to Java. But comparing many other languages, it is not underrated at all. I mean there are more languages which are more underrated than C#.
- gigatexal 8y agoLINQ can be slow. And the language is way too verbose imo.
- dom96 8y agoThat's a bold claim about C# being the only language to get async await right. It may be the one to invent it, but there are many languages that implement this feature successfully. Something I'm curious about, how does C# handle parallelizing async code? Is it hard? Easy? How do you do it?
- akra 8y agoI think C# creates a state machine for every async/await method that is compiles which keeps track of where it is at after every await and invokes the next piece of code based on that. Also I thought async/await came in F# first? According to wikipedia async/await came in 2010 (F# 2.0) and then was added in C# 5.0 two years later.
- andr 8y agoAlso, don't forget that C# had async/await since 2012, 5 years before it was standardized in JavaScript. The only older mainstream (for its time) language to have coroutines is Turbo Pascal 7 in 1992, which was... also designed by Andy Hejlsberg.
- 1wd 8y agoI don't remember coroutines in Turbo Pascal 7, and can't find anything about them in the reference books. Wikipedia suggests the uThreads unit by Wil Barath (from 1995?) but it wasn't "natively" included with TP7, right? http://computer-programming-forum.com/29-pascal/c1ccf8167920b287.htm http://computer-programming-forum.com/29-pascal/c1ccf8167920...
- tigershark 8y agoAsync await is not a coroutine implementation, it’s syntactic sugar over Task and the TaskPool that behind the scenes uses normal threads. Edit: actually it tries to use a coroutine-like implementation otherwise it falls back to the thread poool.
- int_19h 8y agoThey use whatever the current dispatcher is. The default dispatcher is the one that uses a thread pool, because that's the only thing you can do in the absence of an event loop. But the functions themselves are compiled the same, into a state machine with callbacks. That compiled code knows nothing about threads (or event loops, for that matter). It just uses the dispatcher to schedule continuations.
- useerup 8y agoIt does not "fall back" to thread pool. Whenever a thread pool is used, it is because you requested it, e.g. like calling Task.Run(). The async/await implementation will never fall back to thread pool by itself. Tasks are "futures", and in that sense a thread/task pool may be used in async/await when you need to run tasks in parallel. But when a thread pool is used is always under the control of the programmer. Task is a more basic concept than threads. Tasks are about asynchronous execution, thread about parallel execution. Parallel execution is inherently asynchronous, but asynchronous execution is not parallel. Indeed, that it the whole idea behind async/await: Enable the asynchronous model without the overhead of multiple threads.
- mruts 8y agoI haven’t used C# but I’ve found Scala’s monadic futures to be pretty great. Unfortunately they aren’t referentially transparent though. Supposedly scalaz’s tasks are better in this regard.
- atsjie 8y agoThis whole C# async/await hype I don't get? I've come to see async/await more as a hindrance rather than as a good thing. In C# if you're not careful your codebase gets littered with tasks everywhere, even in code that has nothing to do with concurrency originally. Async/await makes concurrency bubble up. This is a great article that explains this issue: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y... It's also why I tried Golang. Once you use goroutines it's hard to go back, since the code is synchronous code. (I use JavaScript with async/await in my day job)
- int_19h 8y agoThe problem with all the other solutions is that they end up being language-specific. That article you've linked to lists the various languages that chose that route: Go, Lua, Ruby. Now try invoking a Lua coroutine from Go, and have it interop properly with goroutines while running. The nice thing about async/await is that it's just a wrapper around futures, which are themselves a composable wrapper around callbacks (semantically; the implementation can be more efficient, of course). So any language that can express function callbacks as first-class values can represent a future, and any language that can represent a future can interop with the async/await world. Which is why you can have JS code doing await on C# code doing await on C++ code in a Win10 UWP application, and it all works. And you can take existing libraries and frameworks that use explicit callbacks (often written in C), and wrap that into futures such that it's all usable with await.
- dom96 8y agoThis is 100% correct. I've never seen this reasoning presented so well before. You're absolutely right, there are languages out there that target the web and the backend on the seever, they can do that and use async await for both targets.
- thebruce87m 8y agoThis is one of those things that sound amazing and powerful, but without a concrete example I have no feeling for how revolutionary it is.
- DSingularity 8y agoWhat do you think of c++ coroutines?
- tracker1 8y agoI disagree on JS libraries having a lack of support... I'd say that most current libraries have Promise support (which works for async/await). You even have async generator support, which is pretty damned cool for an alternate I/O interface that's imho cleaner to work with. Other than that, I do agree, I really like C# a lot and am glad the effort that's been put into making sure Core works cross platform. I still shutter every time I have to work in VS (not Code) though.