7 ms·
.NET languages are amazing. It's fairly easy to program in any style in C# now: imperative, or OO with massive inheritance hierarchies, or even functional-only
by delta_p_delta_x 4y ago
.NET languages are amazing. It's fairly easy to program in any style in C# now: imperative, or OO with massive inheritance hierarchies, or even functional-only with LINQ and things like switch expressions and primary constructors (mentioned in the article). C# now also has top-level statements, so no need for `public class Main { public static void main() {}}`.
The .NET standard library is by far the biggest I've ever seen—it's not merely 'batteries included'; it's 'everything under the Sun included'. NET also comes with a straightforward package manager for third party libraries (NuGet).
There are a variety of development environments available—VS2022, VS Code, Rider, command-line tools. Speaking of command-line tools, the `dotnet` bootstrapper makes it really easy to get started with any sort of project.
The compiler and static analysis tool set, Roslyn, is itself increasingly written in C#, having migrated from C++. With NET 7, code can now be compiled to native binaries ahead-of-time, and there's even an experimental LLVM backend[1].
One can write code for almost any use case (except perhaps embedded) with .NET. It really needs to be used more.
And needless to say: .NET is open-source and cross-platform.
[1]: https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-...
- meibo 4y agoThis reads like marketing blurb but it's really like that. It just does everything you might need it to.
- delta_p_delta_x 4y ago> This reads like marketing blurb but it's really like that. Heh, I was afraid of being called out as a Microsoft shill. You're right, though—.NET really is that good. I'll go ahead and say that open-sourcing the .NET ecosystem is the single best decision that Microsoft has taken in recent history.
- hummus_bae 4y ago> One can write code for almost any use case (except perhaps embedded) with .NET. How so? Do you mean it doesn't support ephemeral ftrace-based tracing or something? That seems unlikely to be true given core CLR features like reflection as well as Microsoft's extensive history of embedding .NET into services and devices.
- jackmott42 4y agoThere could be sufficiently small and performance critical things that you really need to use C/Rust and avoid the overhead of garbage collection all together, or you need deterministic timing and so can't use GC. The performance ceiling of C# is extremely high now though, if you use the low level features. Unsafe blocks, even simd intrinsics! But at that point you aren't really doing C# so much, but at least you can dip into those features for performance critical parts of your code without having to pull out a new language and compiler and complicate your workflow and build tools.
- tannergooding 4y ago> But at that point you aren't really doing C# so much I wouldn't really agree on this point. Unsafe blocks have been a feature since C# 1.0 They may not be the default way of writing C#, but they've always been a natural and integral part of C# and have extensive use internally to ensure that interop can work and extra performance is available where possible. SIMD acceleration has likewise been a part of the BCL (standard library) for nearly 10 years now and is just as integrated behind the scenes. It being part of the formal BCL makes it even more "standard" than the equivalent in C/C++ where such functionality is relegated to compiler specific headers/extensions. SIMD code itself is also very idiomatic C#. There is nothing really different about utilizing the APIs, the only difference is in how you think about handling your data. Needing to think differently about how data is handled for some contexts is applicable to many domains in C# (and programming in general). It's no different than making code work with async or multi-threading ;) Simply put, all these features are still C# and I don't think its necessarily good to say that using them means you're not really writing C# anymore. I view it as a disservice to the language, its extensibility, and power. It also leaves a connotation that you might be better off writing C/C++ instead, which is often not the case.
- Alupis 4y agoEmbedded is a very barren environment. One where bytes of memory and individual clock cycles can matter a lot. This is just not the environment a memory managed language, running atop a virtual machine runtime is suitable for. You'd have to strip all that away, and then you'd just be left with C# syntax, but it would be very far from being C# and would not be compatible with any standard C# library, framework or platform. For a lot of embedded work, even Rust is having a difficult time getting traction. Even the C++ Standard Library doesn't fit on many of the systems folks are working on, let alone the STL.
- brainzap 4y ago"any c# style" describes our code base pretty good, totally unreadable
- jcelerier 4y agoI don't understand why anyone find a mix of style unreadable. That's like saying you cannot read a book which switches between dialogs and narration.
- chasd00 4y agoI want to believe.
- bob1029 4y ago> it's not merely 'batteries included'—it's 'everything under the Sun included' If you really want to get a sense for how broad the APIs are today: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.matrix4x4.createperspectivefieldofview?view=net-7.0 https://learn.microsoft.com/en-us/dotnet/api/system.numerics... I've been working on a custom game engine in .NET for about a year now, and I still haven't had to pull down a 3rd party nuget.
- delta_p_delta_x 4y agoWow. In C++ that would require GLU or glm. I actually didn't know things like this were in the standard library.
- tannergooding 4y agoI got a rewrite for Matrix3x2, Matrix4x4, Quaternion, and Plane in for .NET 8 as well. It should provide up to 48x perf improvements as compared to .NET 7
- bob1029 4y agoAwesome! I believe Vector4.Transform(Vector4, Matrix4x4) is my hottest path right now, but as I get into more complex scene graphs, Matrix4x4.Multiply(Matrix4x4, Matrix4x4) will likely pop into the profiler.
- tannergooding 4y agoFor `Vector4.Transform(Vector4, Matrix4x4)` we had `5.22ns` to `2.46ns` (~53% faster) For `Matrix4x4.Multiply(Matrix4x4, Matrix4x4)` its a bit less at `10.04ns` to `8.38ns` (~17% faster) The main improvements tracked by: * https://github.com/dotnet/perf-autofiling-issues/issues/11442 https://github.com/dotnet/perf-autofiling-issues/issues/1144... * https://github.com/dotnet/perf-autofiling-issues/issues/11480 https://github.com/dotnet/perf-autofiling-issues/issues/1148... * https://github.com/dotnet/perf-autofiling-issues/issues/11467 https://github.com/dotnet/perf-autofiling-issues/issues/1146... There are some more cases to be improved. `Matrix4x4.Multiply` in particular I need to update to use a proper SIMD implementation rather than its current scalar implementation. If you have any other core scenarios where it's important, let me know and I can try to focus on them sooner, rather than later ;)
- harshalizee 4y agoI concur! Coming from Java world to .NET/C#, I was initially very sceptical of Microsoft's offering. Now, I expect to be paid a heavy premium if I ever have to go back to Java. Also, there's a ton of world class third party tooling around .NET that really makes everything better. Shout-out to LINQPad for saving me literally 100s of hours on testing, queries and quick POCs.
- abraxas 4y agoAs a long time Java professional who hasn't experienced .NET what would you say are the biggest advantage points of .NET vs a typical modern Java setup with say, IntelliJ, SpringBoot, maven/gradle etc?
- Kwpolska 4y agoI have very little experience with Java, but I tried building a web app with Spring Boot once. Figuring out even the most basic things, like how to get server-side templates to work, took forever. Many things documented around the web just flat out didn’t work. I got it to a workable state though. In the modern ASP.NET Core, things are much better organized and documented. The framework has far less magic involved. No magically auto-generated repositories, no @Autowired magic, and far less use of annotations. Things just make more sense. As for the language itself, C# is nicer in many regards. Even basic things like properties instead of hand-written or Lombok-generated getters and setters, or operator overloading where it makes sense, lead to clearer code. Regarding IDEs: I hate Visual Studio, but JetBrains Rider is basically IntelliJ for C#.
- runevault 4y agoIts literally IntelliJ for c# lol. Same base system just tied into the Roslyn compiler chain and using their proprietary .NET debugging system instead of whatever they use for the JVM. And while I still use VS at work on personal projects (in both c# and f#) I've switched fully over to Rider and enjoying the experience a great deal, so anyone used to IntelliJ can get a pretty comparable experience from their IDE right out.
- com2kid 4y ago> .NET languages are amazing. It's fairly easy to program in any style in C# now: It is very hard explaining to Java programmers why Java is so bad. Country of The Blind (https://en.wikipedia.org/wiki/The_Country_of_the_Blind https://en.wikipedia.org/wiki/The_Country_of_the_Blind) is very apropos. C# is an incredible language that makes it easy to express a multitude of ideas from a wide range of programming paradigms.
- kasperni 4y ago> It is very hard explaining to Java programmers why Java is so bad Referencing a short story doesn't really explain it to anyone.
- thr717272 4y agoI've been jumping back and forth since 1995. Recently .NET has been very good, but whenever I program in it now and then there are things I miss badly from the Java side.
- pjmlp 4y agoI do both ecosystems since they exist, C# > Java while JVM > CLR, plus even if not standard Java, the biggest selling OS is powered mostly by it.
- naraga 4y agoWhy JVM > CLR?
- ansgri 4y agoIs .NET a viable platform for cross-platform data analysis and visualization tool development now? Python is king here, it sure has everything, but I'm tired of its non-type-safety. From what experience I've had, C# is a very ergonomic language, with good balance between an expressive static type system and do-whatever-when-needed dynamic features. Another language I'm looking at is TypeScript, since everything's in browser anyway, and browsers got fast. Guess I just like Anders Hejlsberg.
- delta_p_delta_x 4y ago> Is .NET a viable platform for cross-platform data analysis and visualization tool development now? I'm not sure there's anything as powerful as Pandas + Numpy + Matplotlib in C# (or almost any other language, for that matter), but it looks like there are a few attempts. Microsoft.Data.Analysis: https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.analysis?view=ml-dotnet-preview https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.... SciSharp: https://scisharp.github.io/SciSharp/ https://scisharp.github.io/SciSharp/ ScottPlot: https://github.com/ScottPlot/ScottPlot https://github.com/ScottPlot/ScottPlot Plotly.NET: https://github.com/plotly/Plotly.NET/ https://github.com/plotly/Plotly.NET/
- torbica 4y ago>visualization tool development This for for sure not. They do not have capable multi-platform UI.
- prmph 4y agoI tried C# recently again, after having migrated to use JS/TS and Node.Js as my main stack for years. What put me off was how cumbersome it seemed to be. Maybe I’ve just been spoiled by JS/TS, but where are the following features (which I believe to be quite basic)? - Union types - Object literals - Functions as first class citizens I get that C# is supposed to be a purely OO language, but in this day, the most useful languages are multi-paradigm. People like to dish on JS/TS but IMHO one reason why they became so popular is overlooked. There’s just something so direct and unceremonious about programming in JS, and with TS you get strong expressiveness as well. Until and unless the .NET languages have that it will be hard to pull me away.
- IneffablePigeon 4y agoUnion types are a gap, although records and switch expressions will get you much closer than was previously possible. Object literals are a thing, they’re called anonymous types. You just new them up. And functions can be passed around as first class objects, with some minor type boilerplate in a few places. There are a few places where you have to adjust to different naming conventions and types are obviously stricter but my experience is that for the most part modern c# has all the things I like about TS/JS.
- runevault 4y agoIt is worth mentioning the c# team is taking a serious look at Union types finally. Considering the runtime already has a version in f# I'm curious how it goes on the c# side of the house (I know semantics are different between the two languages so can't necessarily be 1:1)
- delta_p_delta_x 4y ago> Union types Yes, these are missing in C#. > Object literals You could use records[1], or anonymous types[2]. > Functions as first class citizens There's delegates[3] and lambda expressions[4]. Is there anything that's missing here that you need? You can use lambda expressions almost exactly like you might in JS/TS, even omitting the type: var squared = x => x * x; And if you want even more functional, you could always use F#. [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record https://learn.microsoft.com/en-us/dotnet/csharp/language-ref... [2]: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/anonymous-types https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals... [3]: https://learn.microsoft.com/en-us/dotnet/api/system?view=net-7.0#delegates https://learn.microsoft.com/en-us/dotnet/api/system?view=net... [4]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
- lostmsu 4y agoPoor support for 64 bits in 2023 makes me very sad whenever I .NET
- tannergooding 4y agoCould you elaborate? Do you specifically mean support for 64-bit arrays or something? .NET in general has great support for 64-bit platforms and while it wasn't the default target for .NET Framework, it has been the default target for .NET [Core] for years. We notably don't support single-dimensional arrays that have a 64-bit length or individual objects in general being that large. However, that also isn't necessarily a bad thing as there is a large difference between your overall application supporting more than 32-bits of memory (decently common and generally good) and individual allocations using more than 32-bits of memory (not so common and generally not good to have). If you're creating individual allocations that are larger than 4GB, you're likely not correctly accounting for devices that only have 4-8GB of memory, are more prone to cause memory thrashing, and may end up negatively impacting other parts of the system since such allocations place special restrictions on how the GC can/should interact with the data or in the case of data that is or contains reference types it can add large numbers of additional references for the GC to track. For such scenarios, it's often better to manage your memory differently, to support streaming/buffering where possible, and if it is the rare scenario that actually necessitates such large allocations to use things like NativeMemory to bypass the GC alongside Span or the SequenceReader/Writer APIs to work with smaller chunks of data. This also allows the data to be thought about differently since the algorithm you'd use to work with small to medium sized data is not necessarily the same algorithm you'd want to use when working with large to huge data. The time cost required to process multiple GB of memory is significantly different after all, as is the cache locality and other aspects.
- lostmsu 4y agoArrays might be forgivable (although the other languages including Python, C++, and Rust are not restricted there), but Spans are less so. At this point even my phone has 12GB of memory. Although I am more concerned about deep learning. Streaming tensors doesn't make much sense. The other annoying bit is memory-mapped files.
- pjmlp 4y agoSee Meadow and Nano Framework for embedded, https://www.wildernesslabs.co/ https://www.wildernesslabs.co/ https://sandervandevelde.wordpress.com/2022/12/15/fun-with-nanoframework-running-net-charp-on-esp32/ https://sandervandevelde.wordpress.com/2022/12/15/fun-with-n... Plus many "embedded" scenarios have an OS capable of running regular .NET as well. The problem of .NET versus other alternatives like Java (as an example), is the 2001 - 2014 legacy of being mostly Windows focused, which hinders the choice of libraries and tooling versus those alternatives. For example, coming back to the embedded scenario, .NET has nothing comparable to PTC, Aicas or the endless variants of JVMs shipping on copiers, electricity meeters, M2M gateways and such.