372 comments

[ 5.9 ms ] story [ 265 ms ] thread
Adding spreading is neat, but curious why they chose to go the two dot route instead of three. It's been a while since I've worked in C#, so I can't remember if there are any reserved implications of three dots.
[deleted; I was wrong]
Perhaps I'm misunderstanding you, but I think you have it backwards. It appears that the new array spread being introduced does use two dots, which could mean potential conflict with the existing range syntax?
Hi there. I'm the language designer who created the 'Collection Expression' design/specification: https://github.com/dotnet/csharplang/issues/5354

You can see the entire history of the proposal there. To answer you specific question, we went with `..` because that's what the language already uses for the complimentary 'pattern matching deconstruction' form for collection patterns.

In other words, you can already say this today:

    if (x is [var start, .. var middle, .. var end]) { ... }
So the construction compliment to that is:

    M([start, .. middle, end])
We very much want 'construction/deconstruction' to have this sort of parity, and we will be continuing to follow that principle with new features we are continuing to invest in.

--

Now, if your next question is "why was .. picked for collection deconstruction?" the answer is "because we considered that the nicest syntax from the choices we considered". Syntax is often very subjective, and we often come up with numerous forms to consider (along with examining other languages to see what they've done). In this case, we simply preferred `..` over `...`. The extra dot didn't add anything for us, and we also felt like it might be an operator we might want to use in the future for other language features.

--

Finally, if you're interested in these sorts of questions/designs, def participate on github.com/dotnet/csharplang. We do all our design in the open over there, and are always interested in community perspectives on these sorts of things.

Thanks!

This is why I love HN - info straight from the source. Thanks :)
A general offtopic comment, but something that confused me when I was looking at the github issues and docs for the spread operator.

I've noticed that `...` is frequently used to denote that there's some code that's omitted. However with the spread operator being added (and being `...` in other languages) and "we also felt like it might be an operator we might want to use in the future for other language features" it's a bit confusing at a glance whether that's new syntax or just a shorthand. And it makes searching difficult.

I'm not sure what to replace it with, possibly a comment would be clearer: `/* code here */` or at least `/* ... */`.

P.S. Collection expressions are an awesome new addition!

That deconstruction pattern wouldn't be valid since it can only use `..` once per list. Very cool stuff though, thanks!
Tangentially related but I was impressed with .NET recently. I was recently tasked with tackling an extremely old and proprietary video format that embedded GPS, video, audio, and several other components. The files were huge and just a mess to understand and I eventually found an old player application that was also proprietary.

I decompiled it into C# and stripped the player aspect out of it leaving the code the peeled back the container and allowed me to export MP4 and other pieces. After getting to build into a console application on windows on .net 4 I think I decided to give it a go to upgrade it enough to compile AND run on linux. I upgraded 2x and then updated around 10-15 lines of code that no longer compiled. It was extremely easy considering there were 1000s of lines of code to parse this format. I finally got it running on linux and it only took about a day of full effort. Pretty crazy considering the code I was running was over 10 years old.

The .Net ecosystem has a lot of great tooling, for sure.

The main issue I have had is if you are trying to get into the .Net Ecosystem without spending money. There are quite good free tools, but you have to figure out what works best for you if you're used to the non-free ones.

I assume instead of Reflector for the decompilation, you used DotPeek?

I've used ILSpy instead of JetBrain's tools for this.

If you're a real OG, you used `ildasm`.

> The main issue I have had is if you are trying to get into the .Net Ecosystem without spending money.

I suggest not trying to do this.

You can certainly make most of .NET8 work with a pure OSS toolchain, but your overall development experience is going to be destitute compared to that of the official tool chain. To be clear - I think paid alternatives, such as Rider are fantastic too, but even so I've had some trouble at the edges with paid 3rd party (Blazor apps, UWP, etc).

At the end of the day, you have to ask yourself about what your hourly rate is. If you are going to spend a 20 hour premium per week bandaging up a "free" .NET toolchain, whereas the official, $100/m stack costs you 1-2 hours, which one actually costs you more? What are your principles worth in terms of your free time?

What would you say is the current best in class toolchain for .NET (assuming I'm running on a ARM Mac)?
Jetbrains’ Rider by a very long shot

Vscode stuff is ok too if you dislike big and featureful ides, but it’s behind rider. dotnet cli to run commands is sufficient until you have very strange builds.

Keep in mind the language has many ways to do the same thing, so rider helps you doing the “modern” things. The base class library is also very vast. Take your time, C# is great but it has a ton of features.

What is the issue with using Visual Studio Community Edition? Or if not on Windows, using VS Code with the plugin. All free.
Wasn’t there some issue with debugger on Non-Windows platforms?
The issue that it is free as in beer but not open source as in MIT.
I think you mean open source as in GPL, given that MIT doesn't force to give the source code, hence why it is beloved for commercial products.
Rider is absolutely great, give it a try. I have used and continue to use professionally macOS + VS Code/Omnisharp combo and it has been working nicely with Rider serving as an escape hatch for more complicated debugging scenarios, profiling or when you need to step through (possibly decompiled) 3rd party code.
(comment deleted)
>At the end of the day, you have to ask yourself about what your hourly rate is.

At the end of the day it's a question of how much ROI are you getting. Your hourly rate is irrelevant, when you're just learning a new tech... because when you're hacking/learning the hourly rate is $0.

If you spend 20 hours fixing something that wouldn't occur with the paid toolchain, at what price does it become worth it to skip those 20 hours when they're not directly applicable to what you're trying to accomplish?
Just because you're not getting paid doesn't mean your time is worthless (or your hourly rate changes).
That's where ROI comes in.

Should I have spent my full income for 3 months on an IDE, vs spending an extra 2 hours with the free tools?

It's not a hypothetical, that was the reality of my life in 2004. I had a lot of extra time, couldn't use it to make money and buying "enterprise grade" tooling wouldn't produce any extra value.

The ROI of an professional grade tool would have been - "you get to sleep extra two hours and have no food for 3 months"

> At the end of the day, you have to ask yourself about what your hourly rate is. If you are going to spend a 20 hour premium per week bandaging up a "free" .NET toolchain, whereas the official, $100/m stack costs you 1-2 hours, which one actually costs you more?

Also the official stack is supposedly supported, which means you can contact Microsoft if you have an issue.

In practice, you get some underpaid outsourced employee in the chat, who is just going to follow their script - so it is more effective to go to Visual Studio feedback or Github, depending on the issue.

I teach for a living, mostly people of poor backgrounds, and a lot of them in the Third World. I understand your argument (and I buy some tools myself), but I can't tell them to use paid tools because the cost may be too high in the local currency and it adds up fast.
VS Code and Omnisharp are unconditionally free (and open source). DevKit and VS Community Edition are free for education scenarios. The arguments made in previous comments don’t correspond to reality.
I use JustDecompile. It's free, last I checked, and it works great.
I used dotPeek. Made quick work of it!
Backwards compatibility is something they take really seriously in the enterprise world, but something thrown out the window in the rest of the industry.
I would argue that C#/.NET goes just far enough but not too far with backwards compatibility. As seen in the anecdote, manual changes were required. Java, for example, is more likely to 'just work' but I prefer the language designers' approach to C# and making the occasional breaking change to keep the language in good shape. I really appreciate their good taste.
Microsoft has lot of issues but when it comes to Backward compatibility, no one comes close to them. Solid.
Windows is good at it. .NET is not bad, but also not particularly good — compared to the Java side, at least.
The compatibility shims that come implicit with .NET are incredible. In my experience many of the .NET Framework libraries work right out of the box on .NET (Core), even on Linux.
.net core has been able to run .net framework assemblies since around the 3.x days.

not everything is supported so not all assemblies will work, but large parts of the standard library are supported so it's most seemless.

The new interceptors in C# 12 look pretty wild. Will have to play around with them. Was hoping for more of a PostSharp style AOP framework, and this doesn't appear to be that.
Yeah, interceptors via source generators is hardcore power.

Reminds me of project Manifold[1], the work they are doing is amazing eg. in-line type-safe SQL, GraphQL, etc. Mind bending, beyond next generation level stuff.

1. https://github.com/manifold-systems/manifold

It seems though that you're not going to use interceptors to code up your business logic, or at least not without producing unsuitable code.

What they're likely aimed at is scenarios such as DI frameworks where there is currently "serious magic" code that generates code at runtime using reflection and lightweight code gen; and in new AOT scenarios all of this has to be done ahead of time, during compilation, in source generators, without runtime reflection. In other words, if you're not writing such an DI / AOP library, it's not for you.

But if you want to make a "PostSharp style AOP framework" then this is a tool for you to use when building it.

Apart from the very welcome QoL features in C# 12 (collection literals, primary constructors for ordinary classes), the "Aspire" announcement is very interesting. Haven't decided yet if its a good thing or too much "magic".
Kind of annoyed - I just spent the past week getting familiar with Dapr, and now there's Aspire which seems to have similar goals and is also funded by Microsoft: the Azure CTO even wrote the introduction to the Dapr for .NET Developers book!

And of course the Aspire announcement makes no mention of Dapr - I wonder if the teams have even spoken to each other!

I was asking about Orleans integration. They are working on it (https://twitter.com/reubenbond/status/1724463381686686075).

I think it's a matter of time for Dapr stuff to be integrated. It is after all the first preview.

edit: here's more info about Dapr and Aspire

https://learn.microsoft.com/en-us/dotnet/aspire/reference/as...

Orleans seems to have stagnated greatly past year or two. Someone raised this issue over a year ago(that only like one person was working on it and seemingly part time) and they swore it was still going to be getting resources and continuing R&D.

Fast forward to now and it's only bug and compatibility fixes. A shame cause reminders v2 would have been an amazing addition.

That is how XNA went away, its champions eventually left XBox business unit, and as expected it was back to plain C++ and DirectX, instead of having someone else pick it up.
There were a bunch of new features added to Orleans in the past year, including Live Grain Migration, IAsyncEnumerable support, Cosmos DB & Redis providers.

I think workflows (durable async/await) are more useful than Reminders v2 alone (in some sense, workflows are Reminders v2), but an enhanced reminders system is likely part of that, as is the new log-structured storage system. The log structured storage issue discusses this: https://github.com/dotnet/orleans/issues/7691. We've been experimenting with a programming model for workflows and intend to share that more broadly soon. Currently, we are planning for .NET 9, so feedback is welcome (best provided via GitHub rather than here). Aspire will make it easier to build and deploy Orleans apps, which is one of the harder points for people getting started with Orleans currently.

For anyone following along; Reuben is that "one person" lol.

I was being a bit hyperbolic with "only bug fixes" but.. A bit.

Haven't seen anything around workflows but will check it out and the structured storage stuff. Interested in running my own workflow engine on Orleans and reminders v2 looked like the perfect Quartz.Net replacement for my needs.

Thanks for replying; hoping you would. Someone asked about the future of Orleans 8 on GH a couple weeks back but nobody from the project chimed in last I looked. Know how it is with PMs and BAs and other work though.

Yeah, my confidence is also low. This looks like Dapr all over again.
Is Aspire/Dapr comparable to something like ABP Framework?

Or are they completely different things?

I apparently need to set aside a solid 15 minutes to read the announcement fully. Couldn't figure out what exactly Aspire is just reading the intro and skimming. Thought it was just like a "blessed" set of libs to build with..
Excited about the smaller standalone binary (native AoT) .NET 8 can generate to compete with the likes of Go
Better than go, more like Graal
How is Graal better. Half of the Java ecosystem wouldn't work with Graal.
Half of the .Net ecosystem doesn't work with AOT either.
(Corrective upvote from me. Pretty much any use of reflection dooms you, and reflection is very common.)
Just like with Native AOT, as it only supports CLI, dynamic libraries with C ABI, and a special flavour of ASP.NET with minimal APIs introduced now in .NET 8.

Mono AOT supports a bit more, with focus on iOS and Android workloads.

None of them work with GUI frameworks or classical ASP.NET applications.

MAUI iOS can also be targeted by NativeAOT[0] and Avalonia has been proven to work with it as well.

Also, you can statically link NativeAOT libraries into existing C/C++/Rust/etc. code, and you can statically link existing static libraries into NativeAOT binaries[1].

[0] https://devblogs.microsoft.com/dotnet/dotnet-8-performance-i...

[1] https://github.com/lixinyang123/AvaloniaAOT

[2] https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...

MAUI iOS with NativeAOT is experimental, and is still only of target out of many.

Avalonia is great, however the biggest issue is with Microsoft own tech, as many of us are well aware, many companies are Microsoft shops and only care about what is in the Visual Studio box.

There, not only is Native AOT behind .NET Native, there is no plan to ever support AOT in Forms and WPF projects.

On the libraries I stand corrected regarding static linking.

Lots of very cool stuff here (AOT, Aspire, etc.).

.NET has been held down by the image of its early days, but it has become a pure joy to work with recently. The improvements in tooling and ergonomics have made it a replacement for Go in our org (we migrated from .NET Core 3.1 to Go back to .NET 6 recently).

With consistent, reasonable-by-default threading abstractions baked in
Are those new? What are they by name?
I think the parent comment is talking about System.Threading.Tasks.

I might be wrong though.

Oh, I see. I was hoping for something new. I keep on hoping some sort of BEAM-like (from Erlang) process gets added to .NET.
I have considered the that, but I ultimately decided they work because they are a fabric of what that ecosystem _is_, not what it has.

It's the same reason two sites that are more or less the same will have entirely different communities. There isn't any reason you couldn't implement the one on the other, but it's not in the core substance.

Orleans is definitely interesting, but I have never looked into it much because it's my understanding that it is a cloud-only solution, in that it requires some Orleans or Azure service. Is that correct?
Further to the other reply you can run it alongside asp.net; one process can be an Orleans node and and an asp.net server.
.NET has had first-class parallelism and async/await since around .NET Framework 4.0 release which was...13 years ago huh. There have been many improvements in the underlying runtime since then though.

A garden variety of keywords is async/await, TPL (tasks/futures and structured concurrency) and PLINQ (Rust's Rayon).

You're right the basic support's been around a long time. However, originally you always had to use Task methods. The pleasant async/await keywords didn't arrive until C# 5.0, in 2012.

Admittedly that's also a long time ago.

In addition to the base TPL (System.Threading.Tasks), IAsyncEnumerable<T> in recent .NET versions has deepened and simplified even more useful concurrency patterns (Async Generators), especially when paired with Ix.NET (System.Interactive.Async) which adds a lot more LINQ/PLINQ operators, many of which are designed to intentionally mirror ReactiveX.NET (System.Reactive), the even older but just as useful push-based (IObservable) relative of IAsyncObservable.
Wow that’s a lot of busy work
I just starting using .NET professionally very recently and coming from Go and Java a lot of the .NET platform is just downright pleasant.
At least until it gains an immense market share and Microsoft starts monetizing it again. They've already tried in .NET Core 7, no? I'm staying away for now.
Can you share any details about .NET Core 7's monetization? I couldn't find anything on Google.
It's all open source and free, on Github. I've used .NET for about 10 years now, and the only money it has cost me is a few third party libraries that I couldn't find good open source competitors for.
But you've never seen it with a market share of more than 90%, which could happen eventually. It's a matter of incentives and those play against you.
(comment deleted)
Microsoft owns the .NET trademark but the language and source code for the current runtime is freely forkable and usable by any person/company who wants to do their own implementation. It's no different than the situation with Oracle and Java.
That's actually a very good point. I'll rethink my position.
I don't agree with the person's suspicions, but I can speak to your question.

If you're making over $1M/year or have more than 250 employees, you have to pay for Visual Studio or the C# DevKit in VS Code. Microsoft has been taking the open-core of VS Code and putting proprietary extensions into it. However, this isn't just C#. Microsoft has also replaced the open-source Python extension with something closed source.

There is an alternative to Microsoft's tooling with JetBrains' Rider. Rider is pretty amazing. It's much higher quality than any of the other JetBrains tools and part of that is that the .NET ecosystem is really amenable to tooling (and paying for tooling) and that JetBrains had been creating ReSharper for Visual Studio for a long time (so they already had all the .NET intelligence built out).

There was a thing where Microsoft was going to remove hot-reload from the dotnet CLI tool and make it only available in Visual Studio. I kinda felt like some of this was motivated by timing more than strategy, though. The CLI's hot reload had some rough edges and .NET has corporate style release dates with fanfare like .NET Conf. But the .NET hot-reload is quite excellent. Most edits can be hot reloaded and you can set it to simply re-compile and re-run for the ones that can't hot reload (and it just takes a couple seconds). It's dead simple to use and works (and the amount of time I've wasted to get hot reloading in Java is just incredible).

Really, every ecosystem tries to find some way to monetize. The creator of Elm has a great talk on this: https://www.youtube.com/watch?v=XZ3w_jec1v8.

Microsoft's monetization feels reasonably benign to me. If I'm bringing in $1M/year or have 250 employees, I can pay $500/year/engineer (or maybe less with volume or annual licensing; or $250-420/year/engineer for Rider for an organizational license). Sure, there are costs, but it's not like $500 is that interesting if I'm paying engineers $150,000/year. Likewise, Microsoft likes .NET as a bit of a halo project to get people into Azure. I don't use Azure at all and there aren't really Azure specific features, but in the same way that the iPod/iPhone brought a lot of people to the Mac, .NET probably brings some people to Azure. Even if you're a developer that knows better, you might have someone in your org who thinks "oh, it makes sense to deploy with Microsoft if we're developing with Microsoft." There's a lot of money up for grabs from that thinking. It likely also drives sales of things like Microsoft SQL Server. .NET works great with PostgreSQL or SQLite (and I'd assume MySQL as well, but I haven't used it), but I'm sure plenty of organizations pay for MS SQL Server with the "why not all from Microsoft" thinking.

So yes, Microsoft isn't looking for zero monetization, but the IDE license fees don't seem like a problem - either you're small enough that it doesn't matter or you're large enough that the fee is small. The rest of it is just stuff I can ignore (Azure, MS SQL Server).

But Microsoft's money often comes with some nice things. There's good documentation, a lot of great improvements each year, lots of great video sessions, and some truly amazing blog posts. .NET really has some amazing blog posts - and part of that is that Microsoft gives people the time to create some really high-quality content. If you haven't watched the Elm video I linked above, I highly recommend. It really talks about a lot of the things that money brings to a community. .NET comes with a lot of polish - more than I've seen in any other ecosystem and I've been programming a long time (and I've never been a Windows user).

If the cost of a healthy ecosystem is that companies with enough money to pay a few hundred dollars a ...

(comment deleted)
(perhaps downvoted by those who never had to face with realities of running OSS projects or otherwise)
Do you have some experience here? Mind sharing couple of examples - I'm quite curious
.NET 7? There was no monetizing in it. If you want to look somewhere, look at the C# DevKit for VS Code.
There is no such thing as .NET Core 7, “Core” was a temporary distinction when the Windows-only . NET Framework was still being actively developed, retired with the consolidation to a single .NET with .NET 5.

If you got .NET Core 7 somewhere, I’m sure it is monetized: that's often the point of a scam.

The user is not to blame for the confusing naming that the platform owner chooses.
As someone that knows .NET since it was only available to MSFT partners, I find quite valuable the Core and Framework suffixes, especially when discussing with people not versed in the .NET history, as many people get confused why .NET 4 isn't compatible with .NET 7 for example.
Microsoft's main monetization strategy is to get people to run their code on the Azure cloud.

If it means running code in any lang, on a linux vm in Azure, so be it.

If it means giving away dotnet, so be it.

If it means that dotnet on AWS is also popular, so be it.

They're pretty clear and open about that, you don't have to look for hidden motives.

Big difference is that Go is stable and conservative, net core keep adding a billion features every release. Looking at some net core 2/3 stuff and now to see how many things changed.

Good luck with your code base in 5 years when someone decide to add all the new stuff.

(comment deleted)
I don't know Go that much, but the part about .Net is so untrue. First, C# was published in 2001, while Go was released in 2009. So there's 8 years of "more stuff".

Also (see in comments too), upgrading .Net is very easy. There are man not-to-small codebases can be "easily" upgraded from .Net Core 3 to 8 without any hassle. Backwards comptability was always baked into Microsofts thinking.

.Net 7 and 8 did also (IMHO) not contain that many groundbreaking features, just some "smaller" stuff.

Do you want to compare the number of features added between go and c# in the last 15 years? Just a single major release of C# added more stuff than probably the last 15 years of Go.

I'm not saying Go is 100% right in that, but it's much more conservative about stuff added into the language.

Of course, they conservatively added the most idiotic way of formatting dates as strings (while knowing other methods exist). And, while the whole bunch of other languages would call a method string.startsWith("a"), they use hasPrefix. This language is a mix of half-baked concepts and utter trolling. If I have to learn a lang with an awkward syntax, I'd prefer Rust, Julia, Erlang, Elixir or Haskell. Go is no-go. It's not even widely used at Google, its creator. So no, thanks.
Also, why would force error returns without also including some sort of nice Monadic do-notation or Monad-inspired combinator syntax sugar in the 2020s? We've known for decades now how do that better.

I also think that Go looks like a practical joke that escaped some INTERCAL-like satire committee in the 1970s.

You probably mean sum types and convenient syntax for testing and de-structuring sum types.
No I specifically meant what is often called the Either or Result Monad. These are often implemented as Sum types, but they also follow the Monad laws and supports things like monadic binding/transformation/combination and benefit from syntax sugar like Haskell's "do-notation"/OCaML family's "computation expressions"/the "async/await" pattern of so many other languages now.

Good sum types destructuring would probably also be useful in more languages like Go, but many languages today provide "async/await" pattern syntax benefits without anything at all like "proper" sum types. Sum types are "merely" a possible implementation detail of the Monad and it's the Monad laws that empower some things beyond just sum types.

Why pick on Golang, then? Rust doesn't have a monadic interface to side effects and "errors" either. Nor do the vast majority of the other newer languages.
Rust uses a sum type for most errors (Result<T, Error>) and there are common macros such as "error-chain" that apply a monadic approach to binding/combining them (or chaining them, as the preferred nomenclature in that case).

Exception-based languages don't look monadic at first blush, they definitely aren't Sum types, but try/catch is one of the earliest and oldest of the monadic binding/combining approaches, even if it isn't often thought as such (and is barely considered more than goto/switch). It's far more obvious when you start to realize the intersection of async/await and try/catch is a working monad (and how that is reflected in Task/Promise monad instances).

Golang is the obvious odd one out where every other line of "best practice" code is `if err != nil` and the only other advice is "well you could just ignore errors". try/catch doesn't ignore errors, it just looks like it. Rust error chaining doesn't ignore errors, it just looks like it. Golang gives you the choice between micro-managing errors or BASIC-style "ON ERROR RESUME NEXT" and I cannot get anyone to convince me why this isn't either a practical joke or an intentional throwback to writing code like it is the 1970s all over again (even VB6 had better options than "ON ERROR RESUME NEXT", even if they maybe weren't used as often as they should be in some legacy 1990s/2000s codebases).

>every other line of "best practice" code is `if err != nil` and the only other advice is "well you could just ignore errors".

You have a valid point there, but it hurts my ears a little for you to use the word "monadic" or "monad" to make the distinction between how the way Golang handles errors differs from how other modern language do it. To me, for a language to "have monads" requires the type system to give the programmer the ability to distinguish between a value type, e.g., an integer, and a computation that produce a value type. Haskell's type system for example uses `Integer` to refer to the former and, e.g., `IO Integer` to refer to that latter. And clearly by that definition, Rust and most other modern languages just don't have monads, i.e., don't have monadic types (and consequently don't support a monadic programming style) -- unless perhaps Rust's macro system can be used in some complex way to define the monadic-computational types, but I've never seen it used that way. BTW, I'd actually go further and say that to get the benefits of monadic style, the IO monad or whatever the language calls it must be the only way to perform side-effecting computations (though there is a little wiggle room on the definition of side effect here).

To be more precise, the terminology I prefer is that a monad (in the context of programming languages) is a type that obeys the 3 monad laws: https://wiki.haskell.org/Monad_laws. There are other ways besides a monad for the type system to distinguish between a value and a computation producing a value; Explicit continuation passing is one such way: whereas in Haskell you'd read a character from standard input with `main = getChar >>= \char -> do something with char`, in a language that uses explicit continuation passing, you'd write `main = getChar (\char -> do something with char)` where in this language getChar takes one argument, which happens to be a continuation argument. But all the languages I know about that let the programmer use the type system to distinguish between a value and a computation producing a value use the monadic style to express that distinction (rather than something like explicit continuation passing) so I tend to use "monad" and "monadic" to refer both to the specific thing that obeys the 3 laws and for the deeper programming-language property.

I suppose one of the biggest parts of confusion here is that I'm mostly referring to the monadic programming here in the perspective of the compile-time representations inside of a compiler rather than in the exposed type systems of the languages that they compile. A compile-time representation of computation is a type that represents computation. Not every compiler author themselves think of their work as monads and build them in a way that follows the monad laws/use monad operators directly either, but the overlap should be obvious and a lot of classic and modern compile-time transformations (generators, try/catch, async/await) can be thought of as monadic transformers transforming from one class of monad to another whether or not they are actually implemented that way.

That's one level of confusion in this conversation so far. However, the other problem is that monads don't just mean "computation". (Arguably the Lambda Calculus is way closer to the metal and more accurate to describe as the abstraction of "computation".)

Monads are useful for describing "computations as values" but that's not what the abstraction is entirely for and thinking of monads only as "computations" is how you fall into the easy mistake to make that IO in Haskell is the only "real" monad. There are lots of monads in the wild (Maybe, Either, Promise, List, ...), some of which don't really describe computation at all. We love to mock it, but the technical definition of a monad is "a monoid in the category of endofunctors"; nothing about that is "computation" specifically. Computation is a handy shorthand, of course, but its confusing one of the trees for the rest of the forest sort of thing, mostly because Haskell's IO was the first time monad escaped as a term of art for the deep abstraction that it is.

There is an importance to the monad laws and the two monad "operators", more importance than "computation" as a shorthand for thinking about monads. These operators are called "multiplication" and "identity" in raw Category Theory, but in programming "identity" is usually called "return" and "multiplication" is often called "bind", "bind" is interesting because it also has a dual generally called "join" and "join" is sometimes called "flatMap" or "SelectMany". (Yes, that does point out that most list structures in every modern programming language provide monad operators and obey the monad laws. Lists are a monad.)

A dumber, better shorthand for monads may be "glueable". Monads bind things together in a way that two binds of the same type of monad results in just one monad. (flatMap two lists together and get one list back.) The power of monads is that you can keep gluing things together. Whether by "executing side effects" in a "computation runtime" like the stalwart IO monad or in all the "boring" ways of Lists and Promises and Maybe and Either (that mostly have nothing to do with "computations", except Promises, sort of). The big useful bit is that the Monad laws imply that you can do all this "gluing" in a stable way. That stable way also makes room for the means to transform from one type of Monad to another (Monadic transformers).

Monadic transformers are where some of the real power of the IO monad as an abstraction lives (and other monads in terms of compile-time representations): the idea that the "notation" doesn't matter so much as the end "glued" result. Imperative looking do-notation is the same sort of "glue" as a lot of individual calls to the Monad operators bind and return, transforming from one form to the other is "relatively" "trivial" because the Monad laws say everything should be fine.

There is a usefulness to the...

>if you are defining monads to only mean "the IO Monad"

Show me one place in my writings where I imply that the IO monad (or state monads generally) is the only monad.

The real problem was upgrading from .NET Framework, or Mono, to .NET Core, which has been stable since.

That comparison is not a fair comparison to Go, which has a much stricter guarantee around source and library compatibility within the 1.x series.

People can write dumb, inconsistent code anywhere. A stable library will not protect you from a lack of PR reviews
Thankfully .NET folks are confident that their audience has the skills to manage those features.
.NET / C# seems to be following C++ by including... everything. I wonder if they're just not worried about feature bloat or what's their thinking...
Hi there, C# Lang Designer here. :)

We're always thinking about the bloat concern when it comes to language development. However, our philosophy on it is that bloat primarily comes when you add replacement systems that are expected to supersede the previous mechanisms, not compliment them. So we try to do the former sparingly. In the history of C# there are very few times we've actually done this, and we do view those times as unfortunate cases where we likely rushed a feature too early and then regret having to live with those features forever.

To help combat this, we tend to go through long periods of design and experimentation, where we propose features, create prototypes of them, and then interact with a large set of diverse community groups to try things out. The feedback from this is tightly bound into our design process and allows us to refine (or even jettison) designs rapidly.

We also normally will both break up work into lots of smaller pieces (composing large language changes into small orthogonal, complimentary, composable blocks), and do designs over many years if appropriate. We think this approach has helped us create a language that is 25 years old, while being both very rich, and still very cohesive. There are a few mistakes we've made along the way ("anonymous-delegates", i'm looking at you), but we're very happy that our ratios here are very good given our continued investment in this space.

The new array literals seem to supersede some previous syntaxes like new[] { 1, 2, 3 } goes to [1, 2, 3] in a lot of cases. But overall they are a _great_ addition to the language playing around with them now so bravo.

Still not really sure how I feel about class primary constructors on the other hand, will give them some time to marinate.

Share the exactly same worries. Let us see.
Having moved to writing records by default in many places such as models and "DTOs", primary constructors are a very useful "transition" tool in those cases of "this started as a record, but now needs to be a mutable class for X reasons" and means a little bit less code to entirely rewrite in the first pass. It's also useful for even just "I aesthetically like for my class 'View Models' to mirror their record 'Model' definitions a little closer".
Class primary constructors have always been the default thing in F#, and I found it deeply annoying not to have them whenever I had to write C#, for what it's worth!
C# has been able to add new features while simultaneously making the syntax more ergonomic and elegant, while C++ hasn't.
.NET is stable, they very rarely remove things. Code written for .NET Framework 2.x will probably work fine on .NET 8 (unless it uses the things that didn't make the jump, like WCF, but there are libraries that provide SOAP support.)

Can a single developer remember all of .NET? No, but that applies to most languages/ecosystems. But if you encounter something you've never seen, you can always check the docs.

And the thing hasn't been named ".NET Core" for 4 consecutive releases now.

Actually most wcf code does run on .net 7+ they open sourced it into corewcf. (At least a lot of the things) Webforms however is dead.
> Code written for .NET Framework 2.x will probably work fine on .NET 8

WebForms would like a word.

Hence “probably”. WebForms should die in a dumpster fire.
I worry that Blazor is that dumpster fire sometimes.
I'm curious, why do you say that?
The mixture of client-side and server-side code that Blazor can allow in the same files gives me a very gut instinct feeling that "those who have forgotten the WebForms history, or worse the ASP Classic history, are doomed to repeat it". It's obviously different from both WebForms and ASP Classic and its use of Wasm is certainly a brand new idea that WebForms only wishes it had access to. It seems like a brand new mistake to me, because I still remember debugging ASP Classic and WebForms and Silverlight and "now even the client side JS of ~~WebForms~~ Blazor is no longer JS but a mini-.NET runtime in a Wasm box" doesn't sound like a good time in the long term maintenance future to me when Blazor apps become legacy apps. But some of that gut instinct may just be cynicism at this point.
Ehh, that is the thing about Go, most Go developers know most of the std (compared to other languages at least)
> .NET has been held down by the image of its early days, but it has become a pure joy to work with recently

People have been saying that for the past 4 years.

As someone who's never used .NET but develops embedded apps for Linux, I had high hopes for it become the best story for crossplatform development, it still feels like the crossplatform is held by ductape. It's still Xamarin for mobile, Avalonia (a 1-man project) for desktop Linux as the only choice, 2 confusing different UI frameworks (WinUI vs MAUI). They don't take this as seriously as I'd hoped.

When they made it open-source and cross-platform 6-7 years ago, they should've thrown enough manpower that within 3 years (or even 2, this is Microsoft with endless coffers) it was unquestionably the best development option for nearly every scenario.

Additionally, it's my understanding they don't release proper debuggers on Linux? I'm not gonna install Visual Studio just to debug my .NET app bro.

When it comes to the OSS aspect itself, debugging experience is not the strongest suit but if you overlook it - both Linux and macOS are very well supported by either VS Code / or any other LSP compatible editor + Omnisharp (or DevKit nowadays I guess?) or Rider (which is commercial but is often even better than Visual Studio, definitely faster too).
MAUI is built using WinUI. It is same platform.
Maui is built on top of winui, Android ui and iOS UI. It just looks like WPF, which again influenced winui
Windowing and Widgets; those are the two things that always seem to be the biggest issue for cross-platform apps that should be trivial if the groundwork were in place.

I solidly blame MS for shipping something like 10+ of their own frameworks and never E.G. including QT or anything else open. Apple's just as bad, if not actively worse, for relegating even open 3D modeling languages to second class.

> I had high hopes for it become the best story for crossplatform development, it still feels like the crossplatform is held by ductape.

Sorry to be pedantic, but it's cross-platform GUI that still doesn't have a good, officially supported story.

For non-GUI apps, cross-platform works very well! I've deployed a range of apps to production across Windows, Linux (both x64 and ARM), and Docker on Linux too (also both x64 and ARM) with great success.

I'd like to see an officially supported build for BSD, but that's about my only cross-platform want.

> cross-platform GUI that still doesn't have a good, officially supported story

Yeah, but in the meantime there’re decent unofficial options. Once I compiled NanoVG into a DLL, consumed with C#, and implemented rich GUI on top of that. Worked pretty good overall. Eventually I’ve patched NanoVG for optimal font quality on low resolution touch screen of my target Linux device: https://github.com/Const-me/nanovg

Interesting, I haven't come across NanoVG before!
NanoVG is a 2D rendering library built directly on top of OpenGL or GLES.

Modern rich GUI needs much more than a renderer, but amount and development cost of that “much more” varies depending on GUI complexity. The device I developed is rather simple: low resolution screen, touch is the only input, English localization only, that’s how I was able to deliver in reasonable time.

For more complicated GUI I’d look for different technologies. Maybe QT, despite the high price.

I think it is looking more and more like the established, de facto cross-platform GUI is a web page, embedded into some framework or not. And this is the general wind direction, not just on .NET platform alone.

People say cruft but sometimes I wonder how much more cruft it really is when you use the system browser rather than an embedded web browser. Usually many shared resources for it are already loaded into RAM.

If the end result is something like MAUI, I much rather just use a web page.

Maybe the desktop UI story isn’t quite there yet. But I’ve been using .NET >= 5 web apps for years on linux, and it’s pretty solid with Rider. No issues debugging.

While I would prefer if I could use free tooling, Rider pays for itself in time savings very quickly.

I think that it takes many years to change a reputation - more than 4. A lot of devs don't like learning new things and they would have gotten deep into a different ecosystem before .NET was really open source.

You note that they open sourced it 7 years ago, but the original .NET Core was kinda an experiment. Microsoft didn't quite seem to know where they'd ultimately go with it. I think Microsoft really committed to it in 2018 or 2019. I think you also might have unrealistic expectations of how quickly things can be accomplished. Flutter is over 6 years old and still feels a bit mediocre to me - and I think Flutter is trying to solve a simpler problem since it isn't using native widgets.

For cross-platform UI, I think there is some disappointment in the .NET community. MAUI has succeeded Xamarin (except for Linux), but I think your sentiment that Microsoft isn't investing in it enough is shared by many in the community.

I think the problem is that Microsoft bit off more than it can chew with MAUI. Avalonia, Flutter, Compose Multiplatform, Electron, etc. tend to just paint non-native widgets via Skia or JS/HTML. With MAUI, Microsoft is offering actual native interfaces which means having to deal with a lot of platform differences to implement that rather than just painting their own widgets with a graphics library.

I'm not trying to talk you out of being disappointed with MAUI. It has been disappointing. However, I'm still hopeful for it simply because it's the only effort I see trying to offer a native cross-platform UI dev experience. Flutter, Avalonia, Compose Multiplatform, etc. are all saying "We'll just take a window and paint our stuff in it. Do you really care about an app feeling native?" It isn't always important, but it does feel like so many given up on native apps.

I'm hopeful that MAUI will keep getting better (as it has been) and that we'll have the opportunity for a native UI experience in the future.

This is not a .NET problem.

There really isn't a simple way to do cross platform (Windows/Linux/macOS) UIs with any language. The least bad option is to make it a web page, maybe wrap it with Electron.

Yeah, but MAUI is basically react native, Blazor on Maui basically Cordova/electron (just with much better plugin support) and Maui also had once some support for rendered control.

While I agree it is hard, there is no one who could rule this space better than .NET if they just would like.

Problem is: this is developer division funding which is not the Windows (which owns a UI stack) or office division (react native actually). DevDiv previous UI toolkits WPF was loved but then abondon because of the duplicity of UI toolkits in Microsoft.

It doesn't need to be 100% perfect. Just 99%. Don't let perfect be the enemy of great.

I write Qt GUIs for Linux+Windows, and no Windows user can tell it's not "native" (not that there's a native Windows look anymore, what with MS being schizophrenic about scrapping the UI framework and starting a new one everytime a new PM wants attention, only the classic widget look associated with Windows is still the 2000/XP/7 is recognizable).

Qt apps are super performant, and write once, run anywhere for 99% of GUIs anyone wants to create.

OSX users might be the only one that complain, but they're a tiny minority of users, and it's good enough in most cases, with fantastic performance to shut up the doubters.

Electron apps are hideous, bloated, and slow, relative to the Qt apps I write. I'm only held back by C++ being a shitty archaic language/ecosystem, and if .NET offered an alternative I'd jump ship immediately, that's why I'm so disappointed it's an afterthought.

P.S. Languages designed for "hypertext markup" are not meant to create rich UIs, and can never compete with a native framework. Everything in the JS world to create rich applications is a hack and you can see it in the code and the endless churn of frameworks. When I write something like QML, the intent is clear. When I look at the JS UI frameworks people are hacking hideous HTML templates and conditional logic, list iteration, etc in HTML templates. And nearly every JS UI framework project is written by 1-2 intermediate devs with comparatively little API design talent, who inevitably break backwards compatibility within a year or two.

Yea, I did some Qt work in ye olden times and it's a pretty good system, although it does have its own warts mostly due to being literally older than anything else. =)

I might need to look into it once more, at least it won't run out of steam the second I want to do something else than have a standard text box or an input field on the screen - like all those "easy ui" -systems do every time.

Maybe Eto.Forms on .NET if you want to go native controls and simple for Windows, Linux, macOS: https://github.com/picoe/Eto

It's not from Microsoft but who cares. They don't have a reputation of holding onto new UI frameworks anyway.

Livecode does the cross platform thing
I would love that they support a framebuffer (rendered controls) or Linux native control rendering in Maui for exactly that reason. But no, QT continues it's painful reign.
>.NET has been held down by the image of its early days,

I have been in .NET since 2009. I don't what would lead anyone to replace Go with .NET? That seems like it's asking for a lot of problems you previously did not have.

Can you expound on your decision?

I just wish its cross-platform UIs weren't such a mess. Particularly with its MVCish implementation, it was like it couldn't decide what it wanted to be.

I really really wish there was a good, straightforward desktop GUI for .Net that simply worked crossplatform and wasn't a complete pain in the ass to program.

In their defence, does any other language have one, these days? The landscape hardly looks good, which is how electron et al. got so popular to begin with.
Java and Python have a few. I still don't get how electron got so popular. It's always been pretty straightforward to ship an app with a self-contained Java runtime, much the same as electron ships with v8. Java GUIs have always been worse than c++ ones, but still.. much better than electron I'd say
And now try to get either to work mobile, or in a browser, or at least try to share frontend code between them. That's where electron shines, and all the "classic" frameworks really don't. QtQuick and JavaFX kiiiind of work for at least some platforms, but it's fairly rough all considered, even compared to the inelegant brute force solution of electron.

I'd put my money on the competing "electron, but smarter" solutions that keep bubbling up, rather than any language-centric framework.

I wish that CodenameOne could have been the norm instead of Electron. Unfortunatrly, its desktop port never matched its mobile one in terms of functionality (still uses JavaFX for web views). I still prefer it over Electron where web views are not required i.e. nowhere
I hate that we are completely enamored with browsers. Desktop apps and browser webapps are different platforms, with different methodologies and motifs.

I hate hate hate it when a desktop app looks and acts like a web app.

pySide6 has been a dream for me, it 'just works' and QT is quite robust.

I am currently fucking with Java via GraalVM, and packaging my app for distribution has been absolute hell:

jlink throws errors.

jpackage somehow gets stuck in an infinite loop that generates a directory tree of seemingly infinite depth (so deep that even Explorer can't delete it)

GraalVM native-image can't complete and throws all sorts of weird error messages

Trying to modularize the app has been hell too, it seems like every one of your dependencies needs to be modularized as well?

And like all I am using is Swing, FlatLaf, and MigLayout :(

How the hell are people getting apps running in a standalone environment?

I really like Java the language, but getting a desktop app running on it in 2023 is a nightmare.

I don't know anything about the QT on python as a runtime. Is it supposed to be just as fast since it's bindings to C++, or is it noticeably slower?
I haven't done anything terribly performance-sensitive with it, but what I have written has performed extremely well. My app starts up to its main window instantly (which SHOULD be table stakes...)
> I really like Java the language, but getting a desktop app running on it in 2023 is a nightmare.

This is honestly because you are taking the hard path and trying to do AOT compilation. Just use Swing with HotSpot. Native Image isn't meant for GUI applications and Swing internally uses a TON of reflection.

Using jlink and jpackage with HotSpot has been trivial in my experience.

Try https://conveyor.hydraulic.dev/, we replace or drive the whole deployment stack and have plenty of JVM using customers. It's a lot easier, try it out and see if it works for you. I should say though, that the support for native image is experimental.
When I am ready to mark the github repo as public I was going to consider Conveyor, as paying money for it is a no-go right now (unemployed and broke rn)
Not sure if it suits your use case, but the best I have experienced is jDeploy
Interesting... I like how it piggybacks off npm
>jpackage somehow gets stuck in an infinite loop that generates a directory tree of seemingly infinite depth (so deep that even Explorer can't delete it)

This happens when your jar is in the same folder as the working directory: https://stackoverflow.com/a/64743880

>I really like Java the language, but getting a desktop app running on it in 2023 is a nightmare.

I think it's very easy. Do you use a build tool?

I am using Maven

Getting the jar file is easy. But its deploying it that has been difficult

I think you had a massive number of exclusively JS developers out there who couldn't build a UI outside of a website but wanted to. Then Electron came along and gave them that power. That's how it got so popular, imo.
Lazarus for FreePascal, write your code hit compile and get a nice EXE that starts up on Mac/Windows/Linux
I think you can always train devs, but lots of companies will avoid Lazarus/Delphi like the plague
They should have fixed up Wine to run Winforms flawlessly, and it would have solved the cross-platform desktop problem.
There is not and wont be. MS will commoditize apps to bake as many features as possible as fast enough as possible using some bastardized Electron crap.
Avalonia + FuncUI (for a MVU design) seems to have a lot of fans.
I would say Blazor is really very very good now. One of the most awesome things about it is that your skill with it transfers almost directly between a desktop app, web API, or web site. All the code is almost the same.
Blazor is just history repeating itself. This is Web Forms with a shiny coat of paint and the "magic" this time is WebAssembly and a different proprietary web interface that is undebuggable.

I've heard this "Microsoft has finally created a completely cross platform UI framework" like twenty times...

It is nothing like Web Forms (I've built dozens of Web Forms and Blazor apps so I know), and WASM is just one delivery vehicle for it. You can also render it server side or locally in-process in a full .net runtime (no WASM needed). The debuggability for the WASM runtime has improved alot as well since .net 7.
Not first-party, but AvaloniaUI is doing pretty well in the cross platform department.
AvaloniaUI is miles ahead of any other cross platform library that I've ever used. It actually looks good!
I forgot to mention that I was referring to Avalonia, but when I tried to write something relatively simple beyond the music-player demo app, I got lost in the weeds extremely quickly. Avalonia needs a lot of work on its documentation, there are huge gaps, the quality is really inconsistent, and its abstractions fall apart really quickly
The Windows only desktop UI is a huge mess too. It reminds me of Babbage and his Difference Engine that could never be finished because part way through, he'd come up with "even better" ideas and start a new one.
UI frameworks are a heavy lift, more-so to be cross-platform. Let's say someone tries, but it's not to your liking? I mean, there can't be 12 different frameworks, that's not sustainable.
I am really flexible in terms of a toolkit's ergonomics. But I am running into situations where things just straight up don't work (Java/graalVM), or that I need to implement some really basic interaction and there is no guidance in the documentation and the abstractions don't make any sense. (Avalonia)

And that's assuming it even compiles or packages.

So far the only winner has been QT (via pyside6 for me)

I get it. And I completely agree on Avalonia. Personally, I'm not a big fan of that style programming where xml-ish glues stuff together. Makes hunting down errors a nightmare.
What doesn’t work with java/graalvm?
I outlined my issues in this comment: https://news.ycombinator.com/item?id=38266151

Someone suggested switching the JVM to hotspot and using jlink/jpackage, I am going to give that a shot

Depending on what you want, there might not be too much point in going native. Also, it is unfortunately true that GUI stuff is not yet well-handled by Graal AOT.
I was drawn to the prospect of having a single EXE and having it run as native code

On graalvm 20 I even got it to compile, but there were issues drawing/loading swing components

Not a conventional option, but I've built a few (non-game) GUI applications using Godot game engine + C#. Works great, intuitive once you get the hang of the UI system, fully cross platform (for 3.x anyway - Godot 4 still has a few unsupported platforms - android, web, ios - android support is ready for next release, ios has a PR that I haven't checked up on but I believe it was also nearly ready. Just web that is lagging last I checked.)
.NET 5, .NET Standard, .NET Framework, .NET Core, ... now .NET 8. It's so confusing still.
If you're doing any new work as of the past 3 years, it's just .NET. It's really not that confusing unless you're updating legacy software in which case you're probably quite embedded in the ecosystem already.
Starting from .NET 6 I think, it's pretty consistent. It's just .NET 6, 7, 8, etc.
Still confusing if can't simply switch to the most recent version or have legacy software.

.NET Framework 4.8 will be longer supported than .Net 5, 6, 7 and maybe 8.

This is not unusual in Microsoft-land. If a tech stack or version is very widely adopted or heavily revamped in a new version, they will often support that old version for a very long time - see Windows 7.
No problem with LTS but why the confusing name scheme.

Just like their Xboxes.

The name scheme was confusing only during the "overlap" period. At this point again you can strictly pay attention to version numbers: 8 > 7 > ... > 4 > 3 > ...

Any version < 4 is out of security support. Only one version number starting with 4 remains in security support but you don't want to use it if you can use a higher version number. .NET 8 is new/fresh/current LTS. The rest of the "naming scheme" is dead weight.

Why don't I want to use .Net Framework 4.8?

It will presumably have longer support than .Net 8.

- Lack of features

- Lack of cross-platform support (Windows only)

- Lack of Ahead-of-Time compilation options

- Worse performance

- Disappearing community support (many common/favorite libraries have already dropped 4.8 support and/or maintenance and are only looking at the .NET 5+ present; more do that every day and generally greenfield fresh/new libraries won't even consider 4.8 support or testing at all; this includes major first party libraries such as ASP.NET and Entity Framework, you cannot use the latest on 4.8 full stop)

- Worse and more expensive tooling (8 can be entirely command line driven including locally and cheaper and easier CI/CD installs and scripts, has great support not just in expensive IDEs like Visual Studio or Rider but also [cheap as free] VS Code and through LSP tools even options like vim/neovim/emacs in ways that 4.8 has mostly never supported)

Yes, there's definitely a shift in LTS strategies with .NET 5+. It isn't tied to Windows support lifetimes anymore, which has benefits too (much easier to deploy new versions; I will never miss the days of "we can't use that feature because management keeps putting off the Windows upgrade migration"). It is using a very similar strategy to NodeJS of twice a year releases with "even releases" being LTS supported for two years. That certainly can sound like a more complicated maintenance burden, but faster release cycles and shorter support windows generally mean fewer backward compatibility breaks and an easier upgrade from version to version.

The way I see 4.8 "long term support": the VB6 runtime is still technically "supported" in Windows 11 for long-tail backward compatibility but such long "support" doesn't mean VB6 is a good option for writing code today for Windows (or has been for a decade or more), and the VB6 IDE and compiler have not been supported since Windows XP. Fortunately, 4.8 isn't the VB6 of .NET because there are clear and easy upgrade paths, plenty of good migration tools, plenty of good reasons to migrate (performance! cross-platform!), many developers have happily migrated with no intention of going back, many new developers to .NET have enviably never experienced .NET <5 for many good reasons (Linux support!), and .NET 5+ is still unarguably .NET in every way that matters (the languages are the same, a vast majority of the base class library is the same or distinguishably better). This isn't a hard fork at this point, this is much more clearly "present and most useful" versus "outdated and legacy". But the sentiment of "don't use VB6" is still there for 4.8: if you are still working on 4.8 this year you probably better have the excuse of a large "brownfield" application with a huge legacy footprint. You are probably going to have a bad time doing it, you are going to have an increasingly uphill battle to get new developers to go back to 4.8, and the IDE and tools for supporting 4.8 are going to lose support soon (the ones that haven't already) and will only get more expensive and rube goldberg-like, to be trapped in VMs of older Windows versions and increasingly network isolated because of that.

Every even release is LTS (including .NET 8 today). New projects should not use Framework at all. It's really not confusing at all.
Yes, but that parent has a point: that new LTS is 3 years of support. Which is not that "long term".

We're on .NET 6 now, because it's LTS. But as of today, it has 1 more year of support (1)

.NET Framework 4.8 as an OS component, is actually supported for longer - no end date given (2).

Note that .NET Framework 4.6.2 is supported until Jan 12, 2027 - that's longer than .NET 6 and 7, and maybe 8

1) https://learn.microsoft.com/en-us/lifecycle/products/microso...

2) https://learn.microsoft.com/en-us/lifecycle/products/microso...

(comment deleted)
If you care about support, within 3 years you'll likely need to update dependencies as well which means a recompile. You might as well change your target at that time. Honestly the breaking changes have been pretty minimal lately and it's pretty trivial to upgrade.
.Net 8 is supported 3 years, . Net Framework 4.8 presumably longer.

Confusing.

.NET Framework is part of Windows. That means it is very stable and supported for a very long time. But it is also not possible to evolve it further. That is why the .NET team forked it to make .NET Core, which is cross platform and installs versions side by side. This is what evolved into .NET, most recently .NET 8.
> That means it is very stable

That means "stable" as in "it is not going to change".

But from a developer perspective, binding redirects, brrrrrr.... Also, source-level framework debugging tends to break every so often. It is obvious their focus is on the new .NET.

> .NET Framework 4.8

It was many a moon ago I even thought about .NET Framework. Not everyone might be so lucky, of course.

Yes, I'm in the good place now where I only have to think about version .NET 6 and up.

I would view it as a major, even terminal red flag if I was offered a job involving .NET Framework 4.8 or lower again.

All those terms are consigned to history except .NET

They had to handle a transition phase and as a .net dev at that time, it was surprisingly smooth

It's actually pretty easy if you're new to .NET. If that's the case, it's just .NET 8 and forget about everything else.

.NET Core was renamed to .NET 5, which became the mainline .NET. .NET 8 is simply the latest version.

.NET Standard is intended to be a common layer to help bridge between .NET Framework and .NET Core and .NET 5+. It shouldn't be used outside of that context.

.NET Framework is the old, Windows-only .NET. It should not be used for new projects and should be migrated away from.

Think of ".NET Standard" as "the common .NET Standard on which you can build cross-framework libraries".
It is my understanding that it isn't recommend though anymore. In that it should only be used if you really want your library used in .NET Framework. My vague recollection is that it keeps you away from some of the benefits of the modern .NET.
Eh... since .NET 5 I feel that things have become simpler. If you are writing applications, there is really just the "modern" .NET to keep track of. Occasionally, you have to add "Core" to a Google search to not see results referencing old .NET framework APIs, but that's about it.

If you are writing a .NET library _and_ want it to work with very old deployments, then you also have to care about .NET Standard.

(comment deleted)
It is confusing, but recently it's pretty straightforward

.Net framework is the OG .Net and is windows specific. That stopped at v5 (I think)

.Net Core is the cross-platform reboot that was mostly a subset of framework, but not a proper subset.

If you wanted to write a library that worked across everything, you would target .Net standard, which wasn't a framework itself, but the intersection of APIs that existed everywhere.

Today, framework is discontinued, which makes standard kinda moot, and they dropped the "Core" branding. So as of .Net 6, that's pretty much all you'd write for new code.

If you have legacy code, then yeah you're back in that quagmire

> .Net framework is the OG .Net and is windows specific. That stopped at v5 (I think)

.NET Framework Stopped at version 4.8

That's why .NET (formerly Core) could pick up at version 5.0

I've been thinking about this recently, Microsoft seem to consequently name things in the least intuitive way.

Like seriously: Windows XP -> Windows Vista -> Windows 7 -> Windows 8 -> Windows 10

or: xbox -> xbox 360 -> xbox one -> xbox series x/s

and a bunch of other things, like Azure Devops, which doesn't necessary have anything to do with Azure or Devops depending on how you use it. And their editor Visual Studio, and their other editor Visual Studio Code, which are not really related. IIRC, I also had to make a visual studio account in order to access the azure devops repository at my previous client, even though I don't use visual studio (the editor).

It's seriously like the Fast and Furious franchise.

They seem to be doing it for most of the microsoft products I can name, I wonder if there is a reason for it?

tl;dr:

- Open-source, portable, updated, default choice: .NET Core 1 2 3, .NET 5/6/7/8 - Included with Windows or Unity, frozen in time: .NET Framework 4 (don't use anything older) - Want to support both: .NET Standard (this is a subset that both can run)

Can I get an explanation of the relationship between .NET and Mono?

I have vague memory of reading somewhere that Mono or maybe just MonoBuild was completely obsolete since everything was now open source in .NET.

Does Mono still have a reason to exist? Is it all incorporated into .NET now?

(btw, I still don't get why it's called .NET, and I don't know if assemblies are native code or bytecode wrapped in the same binary format as .exe, where is the ".NET for hardcore open source Linux nerds" blog post?)

(comment deleted)
> Does Mono still have a reason to exist?

From .NET 5 onwards, the framework is cross-platform. So as a separate thing, Mono isn't usually needed or part of the mainstream any more.

> I don't know if assemblies are native code or bytecode wrapped in the same binary format as .exe,

Yes, they are. Either, depending on your build target.

Mono is still used by Unity, and by .NET MAUI for their iOS and Android implementations. https://learn.microsoft.com/en-us/dotnet/maui/what-is-maui#h....

For most .NET apps you can use .NET 5/6/7/8.

MonoVM lives on in the .NET Runtime repo. This is used for non-AOT WebAssembly (or at least it was in .NET 5).
(comment deleted)
In olden days .net was Windows only. Mono was an independent effort to build a cross platform runtime. With .net core MS made it open source and cross platform. They also bought Mono but that is more or less abandoned I believe latest versions of .net run well on Linux and Mac and now also in browser. They have also dropped Core from the name and there is only one .net which is open source and cross platform.

Edit: seems some part of Mono still live.

Mono wasn't abandoned so much as "code merged" (a beauty from that both are now open source). Mono merged into the main .NET repo and the best parts of it became "a single runtime". There are still useful parts of Mono left that aren't exactly inside the "a single runtime" yet, but the amount of "Mono code" shrinks with each version and the more it is all "just" .NET.
(comment deleted)
.NET used to be Windows-only. Mono was a cross-platform implementation of .NET done by a third party and not by Microsoft.

Microsoft eventually created .NET Core, their own cross-platform implementation of .NET, which eventually became .NET 5, 6, 7, and now 8.

Mono should not be used for new projects. .NET 8 is vastly superior. Mono is only still used for things like Unity who have decided to not or slowly migrate off of Mono.

It's not that Unity doesn't want to move away from Mono, it's just that Mono is tightly integrated into the Unity engine making migration difficult. They have announced that they are working on it, but it will likely take years until there is anything usable publicly available.
The answer is complicated, that's why. In a good way kinda - you can build IL bytecode exes that are portable across all platforms and you can also build fully native platform specific binaries too (though there can be gotchas around library support).
There used to be .NET Framework (which was a Windows only runtime built by Microsoft) and Mono (an open source implementation for various other platforms).

In 2016 they started building .NET Core which is new open source implementation (built mostly by Microsoft) which runs on more platforms. For a while all three existed side by side.

Eventually .NET Core caught up and overtook the other implementations. These days Framework is legacy. Core has been renamed to just .NET (since it's now _the_ runtime) and Mono (as far as I know) has been totally replaced by it.

This is all from memory, so apologies for any inaccuracies!

While correct, modern .NET supports currently two VM: CoreCLR and MonoVM. The later mainly as AOT compilation target for iOS, Android and WebAssembly. Mono is still better suited for that, but the AOT compilation of CoreCLR is progressing.

I think there is nothing else left from the Mono project like the class library or the compiler/toolchain.

Actually, .NET Framework is the Python 2 of the .NET world, with all the references that it entails.

Still too many enterprise products stuck in the old ways.

Unlike with python, some things simply can't be ported, though. I maintain a webforms page, the only upgrade path would be a full rewrite
Python 2 => 3 also has the issue that some things don't exist in Python 3, or are done in incompatible ways.

As I mentioned a few times, I have been involved in projects were that full rewrite happened to be .NET Framework => Java, which shows how the customers were mad at what was left behind.

Although there is some irony in that, as Java's Python 2 problem is the transition into Java 9.

> as Java's Python 2 problem is the transition into Java 9

Binary incompatibility between 7 and 8 as well, we got an enterprise product that got bought by SAP and will eternally be stuck on Java 7, but at least unlike the other one, it doesn’t require much maintenance as it’s only used internally ;)

> Python 2 => 3 also has the issue that some things don't exist in Python 3, or are done in incompatible ways.

What doesn’t exist? I don’t like python, but it always seemed like those changes were all relatively minor?

The way unicode was handled, integer division semantics, some libraries went away, and a few other things change enough that 2to3 wouldn't handle everything, which in a dynamic language is a big pain to track down in a huge codebase.

Naturally some changes on the C API for native libraries as well.

Fair enough, thought that still sounds like things where an upgrade path is available, just not automatically, instead of "you have to throw the code away because it simply doesn’t work anymore".
> (btw, I still don't get why it's called .NET, and I don't know if assemblies are native code or bytecode wrapped in the same binary format as .exe, where is the ".NET for hardcore open source Linux nerds" blog post?)

.NET can now do either one - you can ship PE bytecode and require the dotnet runtime, which works in practice similar to e.g. Python or Ruby (you run `dotnet ./myapp.dll`), or you can precompile it into a single platform-specific binary that is just a native code app, similar to Go's static binaries.

I'd love to hear from some .NET fanatics, how would you convince someone to use that ecosystem over another?
As a long-term happy .NET user; you should use what makes you happy.
fair enough, I'm happy with what I've used through my career, but I've never been in a situation using .NET and only tried a hello world.

I think you can always learn something from trying totally different tech, so i'm game to try it for a personal project, but want to hear what people love about it so I can dig in the right direction.

IDK, you can find many basic online articles about "what is C#" and "why C#".

What are you comparing C# and .NET to?

If you prefer loosely typed languages such as Perl, Python, JavaScript then you will find C# too picky about types. Personally, I prefer to have the discipline.

If you are doing low-level stuff where a GC is out of the question then you would prefer C++ or Rust.

But in the in-between space; for most web or business apps, it's very good.

I'm not a fanatic, just a long time user. The tooling and the documentation are superb. Plus the really long term support of everything. You can still compile and run applications that were build 20 years ago, even more.
- It is a mature platform with yearly updates.

- New stuffs integrate nicely with existing features.

- C# and F# gets yearly updates.

- Somehow they manage to get the platform faster every year.

- Microsoft Orleans.

Microsoft seems weird tho. They dont really support any recommended way to do .NET on Mac and you have to rely on Rider or half ass VS Code experience.
What's wrong with Rider?
It's not a Microsoft tool. For a supposedly fully cross-platform language it seems pretty bad to only support first-class developer experience on Windows.
You're right. They did until recently, but it was bad. Now they seem to have moved attention to creating a great experience in VSCode but some of it may require a MSDN sub (they seem to be making the core experience free, with paid extensions to give more Visual Studio-like features in VSCode).
I believe that vs code is the way they want you to do .net on windows as well.

The tooling is all CLI based anyway so do what feels best. :)

Is it "wierd tho" that Microsoft would have better support for development tools on their own OS than on a competitor OS?
It's absolutely weird because that ship has sailed. The paradigm is to hook you into the platform which you can't do if you are hostile.
They support ‘dotnet’ cli, just not an IDE. But we’ve got Rider
(comment deleted)
Rider is so much better than Visual Studio or Code in my opinion, but I understand how the price could be a deal breaker.
I love .Net, but context is key.

I may suggest .Net for new WebAPI development (minimalist or otherwise), typically with a deployment target of containers and or Linux. It is a strong web back-end language in a similar way to Java but with Linq support, async/await, and a better primary programming language (C#). It has strong integrations into corporate software and all popular DBMS. But, frankly, Linq is the magic that makes .Net special.

Otherwise, for new development, I'd pick something else for creating user interfaces. Like Electron on the desktop and a popular TypeScript based JavaScript framework De jure on the web (utilizing WebAPI in .Net behind the scenes).

Have a look at Blazor Hybrid. This is really nice thing. Blazor is the first UI toolkit I actually love for many years.
I have. Too much "magic," and I'm too experienced to fall for that again. No more magic, I should be able to see and understand how every part of my stack works top to bottom.

That's why I'm for isolating the front end from back end frameworks via something agnostic like WebAPI.

With blazor wasm you generally do have separate project for front end and api.
I am talking about that. Not the server side or server to wasm one.

Maybe I use the term hybrid wrong, I am talking about the fat client hosting blazor/web view one. Basically electron shell just without js

Any tips or tutorials for a PHP dev who wants to pick .NET up after a couple decades of not using it? I looked at the project templates in Visual Studio 2022 just for web apps and the options made my head spin.

My wife has worked QA for a number of .NET teams and it just seems like something I should at least keep my thumb on, but I've had nothing but frustration with it so far, even just trying to figure out what template to start with.

I'm not super familiar with PHP -- if you're looking for more of a backend focused project I'd recommend the "ASP.NET Core Web API" template. If you're looking for something that serves HTML pages, possibly the "ASP.NET Core Web App (Model-View-Controller)" template would be pretty straightforward.

There's a pretty good starter tutorial for the Web API one here: https://learn.microsoft.com/en-us/aspnet/core/tutorials/firs...

Or here for the Web App MVC one: https://learn.microsoft.com/en-us/aspnet/core/tutorials/firs...

PeachPie may be worth a look. It’s a php to .net compiler.

https://www.peachpie.io/

Oh dang is that really still around? I remember playing with it like 15 years ago. It's been about as long since I've done .Net
Haha, cute. I'm fine coding in C#, I just haven't done any web projects in forever. Thanks, though!
I'd just create a Blazor project with individual authentication (and don't worry about interactivity). Then inside Components/Pages you'll find code that should look pretty boring. You'll see some HTML, you'll see things like `@page "/counter"` and `@currentCount` and it isn't that hard to understand that the at-symbol means "code thingy" and "oh, @page must be how I specify the URL", and at the bottom there will be an `@code` block. If you look at the authentication pages, you'll see how they handle forms and save things to the database.

There's always more than a comment can talk about, but that's the gist. One good thing is that Visual Studio should be able to help you with a lot of stuff. It's pretty good at keeping you on a good path in the code and pointing out how to fix things.

I think I'll eventually look into Blazor, but it seems really cutting-edge and I'm looking for more basic stuff right now, I think. I'm fine with a vanilla html/js front end (or React, or whatever) and having .net do the server side of things.
You can make a fully functional API service with minimal or no third party dependencies.
.NET/C# + Visual Studio [Code] + Azure DevOps + Azure Cloud = Everything is guaranteed to work for what a software company needs, with full documentation, examples, and a history of variants to explore.

You simply don't have to spend too much time researching what to do, just follow the docs and get started writing code and delivering features.

If you stray from the full integration of MS products, you start to lose some of the value proposition.

No love for AWS huh? I've been impressed by how well their Lambdas work with NativeAOT (they make first-party effort to support it) for low cold-start latency. They have even sponsored further development of Dapper AOT recently.

It's crucial for other major players on the market to participate in .NET if we want to ensure its longevity.

Azure offers a lot of instrumentation/telemetry out of the box compared to AWS.

The more time I spend with AWS the less I like it. Simple issues are left unfixed, implementations are half baked, tooling incomplete.

e.g:

Their configuration extensions package still doesn't support loading a single SSM parameter, despite someone going to the effort of submitting a PR nearly a year ago.

There's zero support for YAML cloudformation templates in their VS extension.

There's no package that allows you to send OpenTelemetry data directly to XRay, they expect you to run an entirely separate container.

The whole platform feels like a jumble of half baked, and poorly exposed services that end up being outright painful to work with.

Dont know about fanatic. I would use it mostly for web backends and there one important part for me has been how far one can get with very few third party dependencies. In a normal backend project it isnt uncommon to only need a handful of dependencies, most from eg microsoft namespaces. Compared to especially Node i see this as a huge security and reliability benefit
Not a fanatic, as I use other stacks as well, however a big fan boy from Anders Hejlsberg work, and naturally the team that picked that up.

.NET and Java ecosystems are the only ones with tooling and developer experience that is somehow comparable to the Xerox PARC world. Note for the pedantic, comparable, not exactly the same.

Given the way .NET was born, there is a kind of yin/yang with both platforms.

Some scenarios or guest languages are better in other platform, while some other scenarios or guest languages are better in the other one.

Given this, when would I suggest .NET over Java?

It is closer to C++ in language features (as CLR was designed to accomodate C++ as well), and C# is getting some of those runtime features exposed since C# 7.

Because of this, and XNA/Unity, also got the love from many game studios (Capcom even has their own fork).

Microsoft also understands GUI much better than UNIX shops, so even with the ongoing GUI civil war in Redmond, most of the GUI offerings are still better than what Swing and JavaFX are able to do out of the box.

Blazor looks really cool as technology, however I was in the trenches with WebForms and JSF, so not really something I would like to experience again.

What did you not like about JSF? I mean, the whole EE part had its fair share of flaws, but I think the JSF model was way ahead of its time, and I still think that (model-wise, not necessarily implementation-wise) it is just unbeatably productive.
View Model Lifecycle as starters, the amount of HTML, CSS and JavaScript boilerplate code that got generated leading to lenghty debugging sessions, and the way most JSF frameworks were basically incompatible with each other.

Example, using RichFaces, and then trying to use something from PrimeFaces, IceFaces, or something else Faces, was always open to surprises mixing their lifecycle expectations.

I was involved with a RichFaces based JSF framework, during three years, and afterwards going back to something like plain JSP and tag libraries felt quite refreshing.

I've used .NET for work forever, but I also utilize it for hobby projects. I can write and install a small C# app on a Raspberry Pi Zero 2 to do various tasks around the house. Very handy and straightforward.
Haven't seen many .NET fanatics, only pragmatics. I'd say that's another argument in favour.
How do you know someone is a .NET developer? Don't worry, they will tell you ;).

I'm sorry but if you compare and contrast the rhetoric and tone of people who are in the .NET ecosystem there is certainly a fanaticism/love for it. And it's often done in a manner that puts other stacks/communities down.

I can't really let this comment stand since it's simply not true.

I say this as someone who has been in the .NET space since 2009.

I think I'd use the argument that "its pretty boring", meaning, it's very solid. However, the C# language is very expressive and get's better every year, so it's a joy to use. It's a great choice for cloud-native server systems. (I feel like this year Blazor is a strong contender against Next.js, so web UI can work well with the backend).
While I might not be the best as I just joined using .NET for an open source application 2-3 years ago, I did just convince my boss to let me rewrite our (really crappy) Java application with a new version (to enable her 2 year vision) in .NET.

Spring boot vs .NET is pretty similar, they both offer DI, Filters, Middlewares, etc. The ways I really proved to switch (given my development team is usually freshers) is to showcase the power of the Identity framework, LINQ (especially with EF Core and the ability to still use Raw Queries), and just overall being easier than Java (LINQ methods, extensions, syntax sugar).

Another big one is how damn easy it is to update and the performance posts MS does with the improvements. So you literally change one line in simple web apps and get performance boosts. Java doesn't really have that PR and the language (imo) is very verbose and painful to use (like their stream API).

All in all, we are building our rewrite in .NET (and Angular 17) and my team and I couldn't be happier.

C# design team is ~5 talented well paid engineers who think how to improve language for past 20 years, every week and don’t let flawed features in and can spend years on how to add async/await, nullables, SpanT and many other features so whole language makes sense and is joy to use. And they have another ~20 engineers implementing features in Roslyn making sure performance of IDE and compiler is acceptable and bug ~free. Unfortunately not many languages can afford that…
This is to the point! That is why C# evolved so quickly and does not spiritually or factually broken.
Great standard library - really good API design.

Very strong tooling. Compiler APIs, debuggers, very strong IDEs (Visual Studio with free extensions and Rider)

I'm not a 10x expert developer so take this as anecdotal, but I've been freelancing a custom Blazor web application for a small business client who manages property - think presenting the user data, letting them manipulate the data, etc., so pretty simple stuff. It's the simplest MSFT framework I've worked with yet, which is a huge advantage to me as I'm using up my time outside of my regular 9 - 5.

Besides the controllers, models, and other things that might be separated from the views, I can mix my html and C# right there in the view - this is the biggest benefit IMO. In combination I use the Entity framework to interact with the DB, which adds to the simplicity.

The costs to run the internal application for several users is going to be around $6 a month for the Azure database. Hosting the web app is also on Azure, and it's free with the basic MSFT domain, which isn't a big deal to clients who use the software internally. This specific client will be saving over $200 a month once I release the app to them.

I can't tell you all the small details that the cool kids might be able to tell you, but I can produce reliable apps in lightening time and make my clients happy, which is ultimately my #1 goal with freelancing.

They link to "Announcing C# 12", but not a single mention of F# and "Announcing F# 8"[1], huh? (Edit: At least there's a link now.)

It actually addresses several warts (finally span pinning!), brings some new shortands, makes the syntax more uniform and comes with some performance improvements as well.

[1]: https://devblogs.microsoft.com/dotnet/announcing-fsharp-8/

One of the first comments on the site points out this lacuna. Leave it to the F# community to be vocal about this.
We gotta be. We know Microsoft isn't gonna be :D.
I'm with ya. I still use F# for scripting in Linux. I've been out of enterprise computing for over 2 years.
I haven't touched .NET in well over a decade. Last time I tried, I felt like a chimpanzee strapped into the cockpit of an F-15. Everything was "deploy!" and "endpoint for automatic upgrades" and "ENTERPRISE" and "web service."

Does .NET have any "write a small program that is only a CLI?" options? Or GUI instead of web interface? Something modest.

Yes, it has all that - console applications with no GUI, GUI interfaces on the desktop as well as web interface - has pretty much everything if you know where to look.
And Visual Studio is probably one of the best if not the best IDEs out there.
Maybe it has gotten better. I found it way too much, but then I am writing Python in Notepad++. All I saw was far too many options and an assumption that you were Writing At Enterprise Scale.
If it was a whole decade ago it's hard to state how much the ecosystem has changed since then.

Since 2014 they've released Community Editions of Visual Studio, with a lot more useful features and less restrictive licensing than the old Express editions.

But if you're used to writing Python in Notepad++ I'd skip VS entirely. You can install the dotnet SDK and just keep using Notepad++.

Here's literally everything to write a CLI app in .NET 7:

A csproj file:

  <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>net7.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
    </PropertyGroup>
  </Project>
A program.cs file:

  Console.WriteLine("Hello, World!");
Then open a terminal and navigate to the folder you put the files in and run `dotnet build`. Or just pass in the folder in the argument `dotnet build .\demo\demo.csproj`.

Voila. A CLI executable is built in the .\bin\Debug directory.

Is there a book you would recommend that targets small-scale usage like mine? A CLI, a GUI, or maybe a Windows Service that fires off every so often.

I have noticed someone in a previous job who wrote an application that somehow tied itself to IIS despite not having any web site needed as a front end and found that somewhere between baffling (was there something I just wasn't getting? Is this how things are done now?) and intimidating (wow, that's a lot of infrastructure for something so small).

I'm looking for something which might target the IDE and little tips like the you have helpfully included.

If you're willing to run Windows.
And if you are not, there is Rider which is just as good if not better than Visual Studio.
Used to be, in my opinion. Specially pre-2015. It has become buggy, slow and lacking features ever since. And let’s not get started with its monstrous setup/installer.
Hi there! I'm a developer on the .Net team, and I heavily work on our IDE offerings. You can absolutely write a small program that is only a CLI, and our tooling is heavily tailored to make that a great experience. First off, you don't need to use an IDE for this at all (if you don't want to). You can just do `dotnet new ...` from the command line to spit out what is needed to do CLI development.

If you do want to use an IDE, there are many choices available. First party options include Visual Studio itself (which has varying skus depending on what you're interested in). For just CLI development, the Community sku would work great. Then there is VSCode, which has both the open-source "C# Extension" (also built by us), and the closed-source add-on "DevKit" which enhances that further with more features".

Regardless of which environment you use, writing a CLI is extremely simple, and the language and environment cater to it. A simple 'Hello World' for C# literally is just:

    Console.WriteLine("Hello World!");
And you can grow on that as you want to flesh out whatever your CLI needs to do. If you're interested in doing anything web/server related, then ASP.NET Core also fits into this very simply, allowing you to stand up a web server from your CLI app trivially.

We def want .Net, including the language, runtime, and tooling to scale all the way from these sorts of experiences to the "enterprisey" space, in a clean and consistent fashion.

If you do run into issues with any of the above, def let us know. You can see all the work we do in .Net over at github.com/dotnet/... Including what's being worked on now, and what we're continuing to invest in for future releases.

Thanks!

That's great to know!

You may not know this, but ESRI is more or less the Microsoft of GIS (Geographic Information Systems). While they largely settled on Python, some of the newer "add-ins" for ArcGIS Pro rely on .NET, instead. As such, I thought it would be a good idea to begin looking into .NET, C#, and the like to see if I could develop some add-ins myself.

I'm one of those solo "dark matter" developers who ends up writing middleware, custom ETLs, and such that almost nobody will ever see and I had begun to despair of finding tooling for "the little guy." I will look into the SKUs you mentioned, it gives me some hope.

I'm looking at a language to write simple executables with or without GUI and that are not too verbose or too complicated. A bit like a compiled python :)

Would .NET 8 be a good challenger ? I previously didn't consider it because the compilation to binary was looking more like an experiment, and the example I've seen were quite verbose (in a java way).

Go seems like a good fit for that.
Yup, Go is absolutely the language for this! And almost every scripting thing you need to do is probably in the standard library, which is helpful.
Go is insanely verbose compared to both C# and Java due to its low expressivity, especially around its error “handling”.
I think you're confusing Go's simplicity and explicitness with verbosity. Yes, it won't help you write the least amount of code, but this forces you to write readable code and avoid cleverness, which is almost always a good thing. Its error handling is an exhausted topic, but avoiding exceptions and being forced to decide how to handle errors where they happen is also a good thing IMO.

On the other hand, I would absolutely use verbose to describe both C# and Java. They are huge languages, with many features, a complex syntax, and conventions and patterns that lead to writing a lot of hard to understand code.

I'd use Go over both of them any day, especially when it comes to writing cross-platform GUI or console apps that can be quickly compiled and easily distributed.

Other options to consider might be Nim or Zig, but these are not as mature as Go.

> I think you're confusing Go's simplicity and explicitness with verbosity

I think those are quite innately related, yes. But I believe you also mix verbosity up in your very next sentence, for what it’s worth — readable, maintainable code is not as close a concept. In fact, certain type of verbosity helps readability, e.g. I argue that Go’s identifier capitalization harms readability, and marking it at a single place by public/private is much better, at a tiny price of more verbosity.

“Clever” code is another topic, there is definitely overly clever code, which is a net negative, but in this particular comparison, is a hand-written, 3-times nested for loop with any number of side effecting statements more clear to read than the “smart” stream/linq expression? I would argue the latter is much more readable and maintainable. For another, even better example there is that math proof, which can be done an order of magnitude faster by choosing a clever notation, but I can’t look up its name yet.

Re error handling, no, go doesn’t force you to handle the errors. It forces you to do some stupid meaningless if err ritual, that won’t result in correct handling of the error case, and will in fact often swallow errors. Java’s checked exception does force you to correctly handle it, though, but even runtime exceptions at least bubble up, making the default action (doing nothing) correct.

It seems to be the more mature language for my use case. How is the GUI development and C++ interop ?
Abysmal. Almost no one does GUI in Go and .NET has had zero/low-cost interop as one of its main features in mind since the very first versions of .NET Framework back in the day.
Personally I use F# for console apps, with ahead-of-time if startup latency is important, yeah. Works fine for me! (Ahead-of-time is much harder with F# though, because .NET idiomatically leans heavily on reflection thanks to C#'s influence, and reflection is banned in AOT. C#'s workaround is source generators, which F# does not support except very unofficially. I therefore find myself stamping out boilerplate for e.g. JSON deserialisation more than I would like.)
> I therefore find myself stamping out boilerplate for e.g. JSON deserialisation more than I would like.

This was my first experience while getting started in the .NET ecosystem. I wanted something similar, I wanted to build small console tools/services and F# looked cool but hit the reflection issues too soon.

I mostly use crystal and golang, but both have their own issues. Hopefully F# improves with time to be fully usable with AOT!

Luckily nowadays C# is just as terse for writing CLI apps or even terser, which does not have aforementioned issues with AOT.
I'm willing to try it, I'm just waiting for a few more benchmarks regarding memory usage. Last time I checked I could only find the Benchmark Game [1] for AoT measurements, but they're from .NET 7.

Memory usage is important to me and golang is very good at that being light, but I really hate writing it for various personal reasons.

If I had more free-time I'd just simply go with Rust but you know, free time is limited :P.

[1] https://programming-language-benchmarks.vercel.app/csharp-vs...

BenchmarksGame is actually an interesting if unfortunate case for C#.

Many tests there are at odds with the areas of optimizations that get most engineering effort investment in .NET: high level and/or application logic and high-performance primitives like Span, Vector, etc. (with the exception of perhaps Regex-Redux, but even there I'm not sure why the results are so low, because C# has one of the fastest[0] regex engines that only loses to Intel Hyperscan, Rust one and PCRE2).

Probably the best way to go about this is to just give it a try with a sample project and see if the RAM usage is to your liking - you can get far with plain 'dotnet new console --aot' and standard library (once you're done, .NET's variant of go/cargo build is 'dotnet publish -o {output folder}').

Overall, .NET tends to have higher memory footprint than Go because its GC is designed to sustain much higher allocation rate and heaps spiking to much higher use without severely throttling performance (which Go does). But there are interesting developments with the new GC mode called DATAS. I made a very simple example project some time ago to showcase .NET's concurrency and publishing experience to someone else which shows that it now rivals Go where it's the strongest[1].

[0] https://github.com/BurntSushi/rebar#summary-of-search-time-b...

[1] https://github.com/neon-sunset/http-bench

Note that I also imported regex-redux into rebar: https://github.com/BurntSushi/rebar/tree/master/record/all/2...

It isn't exactly equivalent to the benchmark game's version. The biggest difference is that it doesn't permit parallelism.

For more details on the benchmark model: https://github.com/BurntSushi/rebar/blob/master/MODELS.md#re...

.NET does well overall in rebar's benchmarks, but less so in regex-redux (in both the benchmark game and in rebar's version of it). Not sure why. I haven't investigated. Of course, this is assuming you aren't using .NET's default interpreter engine. You've got to switch to the no-backtracking or compiled modes to get decent perf.

It would. Compiling .NET binaries to a single executable that does not require installing a runtime has been a thing for quite some time actually, but NativeAOT definitely improves the "simple and lightweight" part of your inquiry:

JIT: dotnet publish -p:PublishSingleFile=true -p:PublishTrimmed=true

AOT: dotnet publish -p:PublishAot=true

Looks interesting! Does nativeAOT works for GUI ?
It's a bit of a hit and miss as of today. CLI, back-end and natively compiled libraries (think dll/so/dylib or even .lib/.a - you can statically link NAOT binaries into other "unmanaged" code) work best, GUI - requires more work.

Avalonia[0] and MAUI[1] have known working templates with it, but YMMV.

[0] https://github.com/lixinyang123/AvaloniaAOT / https://github.com/AvaloniaUI/Avalonia/

[1] https://github.com/dotnet/maui (try out with just <PublishAot>true</PublishAot> in csproj - it is known to work e.g. on iOS)

It depends...

.NET 6 was already capable of most things you are looking for, but there are some limitations. I personally think it is a really versatile language and if you know it, you can get the most things done somehow.

I wrote a little cross platform C# command line tool called `tone`[1] for tagging audio files and it compiles via github actions for windows(x64), linux(x64,arm64,arm6,arm7), macOS (x64, arm64) as a single monolitic binary (similar to `golang`), which is pretty cool.

With the right compiler flags it is not even too big (about 20MB, for comparison a `golang` binary with similar features would be about 5MB, `rust` more like 1MB or less). You can also go WASM (which is generally supported, but feels a bit experimental at times).

In the GUI department there are three main competitors:

  - MAUI - Windows, macOS, Android, iOS (Microsoft's pet, xamarin successor)
  - Avalonia UI - Windows, Linux, macOS, Android, iOS, WASM
  - Uno Platform - Windows, Linux, macOS, Android, iOS, WASM
All these feel kind of unfinished, I like Avalonia UI the most, but it's lack of standard libraries for real world apps (Preferences, SecureStorage, Encryption Wrappers, Phone-Hardware-Access, Media-Players, WebView) and the outcoming App Size (>50MB) made me use Flutter for my personal projects (App size ~15MB for the same feature set). For some Apps it might be ok.

.NET may also still be incompatible / unfinished on other OS and platforms (e.g. RISC hardware or BSD operating systems). So if you only target the mainstream systems like x64 and the raspberry pi, it might not be a real problem.

[1]: https://github.com/sandreas/tone

I would target the main desktop, and maybe raspberry and android but it's very far from my horizon and not a criteria.

I was thinking that flutter is a dart library/framework ? How is it compatible with C# ?

Flutter is written in Dart, nothing to do with C#, but a cross platform UI library.

I think Flutter has a lot of advantages over the C# UI libraries and is worth learning when planning a Cross Platform UI or App.

It's possible with C#, but you have to work around a lot of shenannigans depending on the use case.

Command line apps are totally ok with C#...

It may go under the radar of many but .NET 8 comes with DynamicPGO which is now enabled by default (improved since its earlier iterations in 6 and 7, which were opt-it).

It will help numerous abstraction-heavy codebases the most thanks to guarded devirtualization of interface/virtual calls, delegate inlining and branch reordering which has progressively more impact the more bloated code is.

Seems like AOT compilation is spotty on Asp.NET apps. A fresh app made with dotnet new webapi -o aot-api did not work when run.
Killing that startup JIT is important if you want to scale out fast.
I haven't completely followed the AOT stuff, but I remember hearing some stuff about some reflection-heavy code doesn't play well with AOT.

But .NET has a great option in this case: ReadyToRun. Basically, it AOT compiles a ton of stuff, but also creates the byte code which can be JIT optimized at runtime. The file output is larger which is a downside, but is usually a very minute downside. ReadyToRun takes care of start up times because you have the machine code to get things running fast. Plus, the JIT can sometimes make optimizations that can't be done at compile time so you can end up with better overall performance (at the cost of a larger executable file).

One of the things that is nice about .NET is that a lot of things come with sustained, multi-year effort with some good things coming every year. Microsoft is working on making more and more of .NET AOT-friendly and really upgrading the way things are done. Along the way, there are things like ReadyToRun which work really well for what most people want/need.

Give 'dotnet new webapiaot' a try (you can see more details with 'dotnet new list' or 'dotnet new {template} -h' to see extra options for a specific template).
ASP.NET with AOT is only supported in minimal APIs, nothing else.
As full stack .net dev, I am so disappointed every “who is hiring” thread. I would be game to join a trendier group of like minded devs but if you get one .net posting you are lucky, and it’s most likely rockstar.

:(

I think an issue here is that .NET was closed source for most of its existence. It was only 2019 when Microsoft announced that the open-source .NET would be the future of .NET. That will mean that a lot of startups wouldn't have chosen it. Even now, it means that a lot of the "trendier" devs will have learned other ecosystems that have been open source for longer.

It takes time to shift developers.

Microsoft started open sourcing .net framework on 2007 with 3.5 version.

The roslyn compiler is open source since 2014.

I guess it's fine if people don't like .net but I think the open source part is not that relevant.

I think it depends on who you are. In 2007, a lot of people distrusted Microsoft and with good reason. They'd spent a lot of time extinguishing competitors. .NET Core was initially released in 2016, but Microsoft wasn't saying that .NET Core was their plan for the future. It seemed like an experiment they'd likely kill off or that it might just be a small subset of .NET.

I think saying that Microsoft started open sourcing .NET in 2007 feels a bit disingenuous. Plus, wasn't it source-available under the Microsoft Reference License? Regardless, .NET was still tied to Windows unless you wanted to use Mono (which was slow and had an uncertain future).

If you were someone who developed on Mac or Linux and deployed to Linux, you couldn't choose .NET in 2007 or 2014. Even in 2016, are you going to choose a brand-new ASP.NET Core? Microsoft announced .NET Core 1.0 at the Red Hat Summit in 2016 which isn't exactly an endorsement that the company thought it was the future of .NET. It seemed like Microsoft was trying to open up just enough to hook a company on .NET Core and then tell them "well actually, you should really upgrade to the real .NET Framework on Windows" when they ran into problems. That's not what happened, but Microsoft certainly hadn't committed to .NET Core in 2016. Their messaging was "well, Red Hat will offer support for this thing we made."

If I didn't have a Windows PC in 2015, I couldn't do .NET development (Mono aside). If I wanted to deploy to Linux in 2015, I couldn't do .NET development (Mono aside). The open source part matters to lots of people because .NET simply wasn't a choice for those who didn't want to be beholden to Windows and licensing until recently. People definitely ignored .NET because it simply wasn't an option for them.

My feeling was that Microsoft open sourced the .net framework to help Mono catchup a bit.

As for access to windows, to be honest I think that's pretty easy to have. Run on general purpose hardware, it's not that expensive.

I think that having access to a Mac is relatively harder than having access to a Windows machine.

When .net core came out I was under the impression that the product was the future of .net but maybe I was living in a bubble.

Anyway, I understand your point but I still think that the disinterest towards .net is tied to a generalized adversion to Microsoft (probably deserved) but not really related to the tech itself nor it's availability on Linux or Mac.

More important than being open source was the fact that it was Windows only for the first 15-ish years of its existence.

Mono never got traction within the startup culture. In part, because it operated in a legal grey area for many years regarding MS patents for web (or web adjacent) technologies like ASP.NET and ADO.NET.

Microsoft made some extremely generous patent grants to Mono and several major Linux Distributions relatively early in Mono's history. Microsoft didn't seem to want to repeat the mistakes that led to their divorce with Java and the early foundations of .NET with their relationship with Mono. In my experience of it, most of the "legal grey area" concerns around Mono for a lot of its history was either truly outdated/ignorant advice or intentional FUD from antagonists (many of which just hated anything Microsoft indirectly touches no matter what).
It was 2016 when you count official releases, open sourcing .NET to MIT started in 2014 including huge parts of the .NET Framework.

It is soon 10 years. With 14 years of closed source before. But honestly, it is not .NET which is the problem maker, it is Visual Studio on Windows. Because that is the thing which cost and the thing which only runs on Windows. I hope they fix it in favor of VS Code (which looks good right now).

But I agree. It takes time.

There are plenty of traditional corpos hiring for .net roles but not many startups choose it as their stack
I hope Blazor will replace JavaScript some day. I am tired of learning a new JS framework/library/etc. every 2 months. Time to end this.
I am no JS fan, but to be honest that new framework thing has not been a thing for half a decade. React is the de facto standard, plus a few smaller frameworks are what everyone uses.
Blazor actually looks compelling now that it has server side streaming and rendering, as well as component level interactivity.

Once .NET is integrated with the new WasmGC features, it will get even better! (I don't think they mentioned WasmGC on the roadmap but I can bet anything they're going to do it).

I am slightly surprised they still did not replace it with some 80% similar "WasmUI". Which XAML framework are we on now by number?
You could run Maui with canvas rendered controls. Just some coding work away.

But honestly, .NET is a enterprise thingy. Normal for them is that they coexist with angular, react, and many other UI toolkits. Reuse of css and web components is the customer need, not a Silverlight.

Yes, it really does. It means that you can use component style development while having a regular server-rendered app. If/when you want some interactivity, you can add it simply without much effort. With .NET 8's Blazor, you can just have regular pages for 90% of your stuff and just use WASM (or websockets) for 10% of stuff. The good thing here is that you get fast initial page loads and navigation and the disadvantages of WASM are a lot smaller (like larger downloads than JS since it's shipping a GC and such).

.NET is following the WASM GC stuff. There are some Post-MVP features for WASM GC that will benefit .NET. Note, I'm not an expert on this and this is coming from memory. That said, .NET has some features that won't be supported well by the WASM GC MVP. There's always a trade-off between supporting more and getting stuff out into the world so that languages that might not need the features can start using it (and they can learn from the usage which will benefit everyone). For example, .NET allows more pointer stuff than a lot of GC'd languages. .NET's `unsafe` isn't used much by most .NET programmers, but it is there. I think maybe .NET has stronger guarantees around finalizers than Java (where they aren't guaranteed to ever be run). The WASM GC is just an MVP at this point, but it has landed and they're working on its future. It really feels like we're getting to that point where WASM is going to really offer a better experience in the near future.

Ultimately, the timing of WASM GC wouldn't work out for the .NET 8 timetable, but I'd expect there to be a lot of work on it for .NET 9 next year. It's possible that a lot of Post-MVP stuff will land in WASM GC to help .NET and there's probably some opportunity to make Blazor work around other stuff. I think they haven't mentioned it or put it on the roadmap because they're still figuring out how it's going to go (and we'll probably know more in like February). But they are certainly looking at WASM GC and it's likely to offer a nice boost for .NET 9.

I want to want to use it but have tons of questions would need to research.

Building a professional component lib is a pita. Last I checked there were a billion React component libs and like one OSS Blazor lib in progress. Plus the usual commercial libraries you typically see in the .Net ecosystem.

Accessibility is a pita and aria requires JavaScript. How does this work?

State management in a way that's extendible? I love Mobx but the only thing active is a fluxor lib(yuck). Can other JavaScript code even plug into this?

Extensibility in general. Can new functionality be added via dynamic loaded plugins?

I would end up needing to interop with a parallel JavaScript(Typescript) codebase. My msbuild foo is pretty strong these days but would be nice to have a straightforward project config accounting for this.

Super stoked for a few things.

List expressions I'm overly excited about. Can't wait to use and of course dictionary expressions will be amazing in the future.

EF Core complex types. Also it'll be fantastic when these can be used to model composite keys.

The using enhancements. Hopefully I don't end up overusing tuples.

If Orleans had secretly been working on reminders v2 it'd be early Christmas.

Been away from .NET for many years. In those days, business logic was largely represented as procedural code using classes for organization, manipulating recordsets or datasets.

Is that still the case?

You can use micro-ORMs like Dapper, but I don't how you would do anything else than classes to represent your result sets unless you want to stuff everything in a dynamic ExpandoObject (which you can).

In that case, go back to PHP or where-ever you come from ;-)

You can use an object domain model to model a complex system. Something more common in say Java than .NET with its traditional “wizard” based tooling legacy. Worth looking up if all you know is recordsets and datasets.
Yes, active records and such. There are various ORMs in .NET that allow this.
Also, in big corporations, getting approval for spending $20 is as hard as getting approval for $200 or $2000.

Which is why FOSS software took off in big companies, because it's easier for developers to sample things out and then ask for forgiveness instead of asking for permission.

Also, hobbies. It doesn't even matter if you have $20 to spend, or not. Hobbies depending on paid tools are risky.

People underestimate the importance of free tools because they judge from the perspective of their overinflated consultancy rates.

Then again, this sort of decisionmaking is probably why you're a software developer with less than $20 in your bank account.
I don't know... Possibly because your life circumstances made it that?

But hey! Talented people doing their best to break out of poverty is clearly a novel idea to you.