Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C# nails this consistently, it's not worth hand waving it away because it isn't FOSS. Rust drama itself suggests that a FOSS language doesn't shield it from corporate meddling.


The C# compiler has an MIT license and is available on GitHub, which is about as FOSS as it gets.

https://github.com/dotnet/roslyn


The compiler is one thing, the ecosystem is another.

Sure, you can compile and host your .NET Core web app on Linux these days, but desktop applications are a completely different beast. You're often lucky if one exists at all, and if it does there's a decent chance it's not designed for "modern" C#-on-Linux. It really isn't a viable option yet, maybe in a decade or two.


WPF is MIT licensed, available on github. The fact that it's windows only doesn't make it less FOSS. Microsoft doesn't have incentive to port it to other platforms but other people and companies are free to do that.


WPF is not the best example of open source, as some components are still closed source. Though it only runs on Windows, a closed source operating system, so perhaps that is not so important.

https://github.com/dotnet/wpf/issues/2554

That said, there are cross platform, open source .NET UI frameworks out there, including one that is inspired by WPF:

https://avaloniaui.net/


The issue for me with languages like C# is the lack of expressiveness.

Sometimes classes aren’t the abstraction I want to use.

That’s why I like kotlin over Java or c#. It’s be nice to have a language like that which targets .net


You should try Java and C# again. They have added lambdas and the support for high order functions is quite good. Sure, there is missing some things like guaranteed tail call optimization.



Actually they were made for other languages given the original goal of Common Language Runtime, as published on the 2001 release note.

https://news.microsoft.com/2001/10/22/massive-industry-and-d...

Anyone with the pre-release MSDN .NET SDK that was initially made available to MSFT Partners, with alpha documentation written in red, has a folder with tons of functional languages that could take advantage of tail calls.

F# only came later into the picture, even considering its OCaml for .NET origin.


Not the person you replied to but, today I learned!

As an aside, and as someone who's currently going through materials such as Crafting Interpreters (and who knows what else based on suggestions from r/compilers), is there a, I guess, guide for people who want to implement a compiler that targets the CLR/CLI?

I have a copy of CLR via C# 4th edition, but other than that not sure what else I can reference targeting anything newer than .NET Framework 4


I don't have something that could be of Crafting Interpreters level on hand, but the general suggestion given to this question on DotNetEvolution discord by Roslyn team members was to start with the spec itself: https://ecma-international.org/publications-and-standards/st...

This might be a bit of a learning curve if you don't have experience with writing compilers like that though.

There are other materials that might prove useful should you go down this path:

- A series of blog posts of a student who is writing a Rust to .NET compiler which you could follow along: https://fractalfir.github.io/generated_html/home.html The project itself: https://github.com/FractalFir/rustc_codegen_clr

- A video series on writing a compiler for .NET from scratch: https://www.youtube.com/watch?v=wgHIkdUQbp0&list=PLRAdsfhKI4... Notes: https://github.com/terrajobst/minsk/tree/master/docs

As for CLR via C#, while it has certain facts that remained the same, the ecosystem has changed a lot since then, you really want to target the latest LTS to get best experience and performance. If you liked it, then I can strongly suggest https://github.com/dotnet/runtime/tree/main/docs/design/core... which covers .NET runtime internals.

p.s.: if it's any consolation, the promise in CLR via C# of JIT having the advantage of dynamically profiling code execution and compiling to profile-guided version, tuned to the exact hardware and environment is finally fulfilled, many years later :)


I have tried C# recently.

They have support for these features, but they require some ceremony to use (like wrapping function arguments in a Callable), which increases friction, signal to noise ratio, and decreases the expressiveness that I want.

I just want to write what I want without having to think too much about how the language wants me to write it. Go is good for that. JS too, but has a lot of historical cruft.


I feel like your "recent" must have still been years ago. Modern C# is as terse as Python/TS/Js for basically any equivalent task, if not more so. Dotnet 8 even make the following possible:

var foo = [1,2,3];

Add on switch expressions, primary ctors, first class functions, no ceremony in Program.cs anymore... it's hard to get more terse and expressive unless you want lots of chained single symbol operators (look at F#).


(slight correction: `var foo = [1, 2, 3];` requires natural types for collection literals (it needs to infer the best type for var), this is coming in C# 13 (.NET 9, this November), but otherwise `int[] numbers = [1, 2, 3];` works)


You're right! I remember some session where they talked about wanting to infer a natural type for stuff like that but its obviously a big question. But as you said declaring the type directly allows it to work. However the other nice part is that you _can_ do this:

void myFunc(List<int>){}

myFunc([1,2,3]);

The expression sytanx can infer the type from the caller syntax so you can just inline the array declaration.


My recent was a month ago, but to be fair, the CTO of that company (who wrote the existing code when I joined) last wrote production code in 2008, so his code may have not been using those newer syntax features.


Yeah it's very easy to write Java style C# that is incredibly verbose and rigid, but once you understand modern c# you can see how it's this really great (imo, awesome) hybrid of functional/typed languages. They've done a ton of syntax work to let types get out of your way when you need them to, with the ability to always fallback to rigidly declaring them when you need better readability.

The downside of all this is that the only people that know how awesome C# is are people who are already doing C#. Growing the pot and trying to convince people to give it a go in its modern (post dotnet 5/"core") iteration is like pulling teeth. Everyone assumes nothing has changed since like C# 2, and given the fact it's a "boring" language that doesn't have Hacker Hype behind it, people just ignore it.

Every week you have people on HN wishing for something that does exactly what C# does but don't want to give it a shot or admit that C# is _actually_ an incredible language and toolset that does exactly what they want (and more).


C# offers multiple options for abstracting away functionality. What do you have in mind?

Also, JVM ecosystem does not offer the ability to provide zero-cost abstractions, which C# does with monomorphized generics. This is a hard requirement for productive systems programming if you don't want the C level of verbosity.


> Also, JVM ecosystem does not offer the ability to provide zero-cost abstractions

This is true, wasn’t thinking about that.

C# always requires me to use and organize my code into classes and my data into objects.

For example, If I wanted to use higher order functions, I need to wrap functions in callables (Objects).

If I wanted to throw together a quick script to test, I need to set up a program which uses some magic configurations so that I don’t need that entry point class.

Granted I only worked with C# professionally for a couple of years before getting back to a Go shop, but it always felt like trying to avoid thinking in objects was fighting against the language.

Personally, I like just having first class functions which take simple data structures as arguments. Modeling the world as objects just isn’t as clear to me (the old OOP vs FP discussions)

Languages like C# and Java turn me off for that reason.


Are you sure you are talking about C# and not some other language? There is no such thing in C# as "callables". It has lambdas, Funcs and delegates.

It has always had a fair share of FP features and only gained more as it kept evolving. It had higher order functions partially in the form of method group to delegates conversions since C# 2.0, released 19 years ago and to a full extent in the form of lambda expressions since C# 3.0, which also included LINQ, released 17 years ago. It is a mixed-paradigm language.

On the off chance that this is trolling, I must point out that Java and C# are sufficiently distinct, with the latter leaning more heavily on offering both lower and higher level features like extensive pattern matching, LINQ, structs and pointers/byrefs.

If you do have C# snippets you are unhappy with - please post them. There is likely a better way.

(I noticed you posted about Callables twice, and had a quick search - it appears to be a Godot-specific abstraction imposed on C# due to inadequacy of GDScript it has to interoperate with, and has nothing to do with C# itself)


Callable may have been the wrong word. I think I meant delegate. (I do work with Godot, but not in C#. Some wires must’ve gotten crossed)

Regardless of the actual word, there is an extra thing I need to do to pass a function to a higher order function as an argument.

I was using this as an example to demonstrate how C#’s support for the language features I like require some ceremony which reduce expressiveness and require me to think about the language more.


You didn’t. The example does not exist and the terms you used don’t apply to C#.

Post an actual example (code).


Delegate is a C# term and was what I was talking about

https://learn.microsoft.com/en-us/dotnet/csharp/programming-...

I need to create a delegate for any function I want to pass around.


Trolling is bad, consider asking ChatGPT or reading documentation first, thanks.

    var func1 = (int i) => i + i;
    var func2 = () => func1(1) * 2;
    
    Console.WriteLine(func1(4) + func2());


Unity and Godot are both a bless and a sin for C#'s adoption.

In one way, they help the adoption in the games industry, in the other hand they introduce so many anti-patterns with their reflection based SDKs, and use of magical methods instead of proper .NET code.


Exactly.

I used C# for a long time, and when I started using JS, I marveled at the directness of its expressiveness, its lack of ceremony.

What's actually needed is a language as direct as JS, with the bad parts stripped out, types and a proper standard lib added, and compiled to byte-code for performance.

They can call it a different name if they want.


You might like AssemblyScript (https://www.assemblyscript.org/)


Yeah that “directness” you’re talking about is what I call “expressiveness”

It’s important for how I like to code.


Valhala might help there, but yeah, we are still a couple of years away and currently the best is to manually model memory with the new Panama API, definitly not the same league as C# / .NET today, which I consider the closest modern language to what Modula-3 has promised us.


In what ways is C# the closest to Modula-3's promises?


Now that AOT is part of the standard toolchain, with plenty of Midori, and C++/CLI capabilities also exposed to C# Language level, a memory safe systems language with a modern type system.

I would also place D and Swift into that bucket, only D never managed to really take off when it had the opportunity, and Swift is clearly at home in iDevices.


Thanks.


Those are good points, but my problem with c# is that it isn't as performant in Linux. On Linux I'd suggest go as the more performant option. In any case I like both of those so much more than swift. Swift is slower even with bounds checks off. You can't turn them off in go.


> but my problem with c# is that it isn't as performant in Linux

Any evidence for this? From the benchmark game it seems like c# is more performant than go, and measurements are done on Linux.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...


I think it is because I generally look at a given benchmark there and don't browse below the "optimized" section to look at solutions that use intrinsics directly. Being able to use intrinsics directly is a great feature, but doesn't fit in with the whole "fast but not so fast I need to worry about safety" theme. When you exclude solutions that use intrinsics, go is faster. I use rust as my daily driver at work and home. I don't think I'd select either go or c# for a project. When I just want something that works, and I'm not worried about performance, rust is easy to use. It is only when I'm trying to squeeze out performance it gets hard. It is hard to convince go that it is safe to skip bounds checks, and while writing intrinsics isn't hard, it isn't very portable and you have to write lots of versions unless you metaprogram it, which I find harder than idiomatic code in any of these languages. Squeezing out performance is easy in c++, even in c++17, but it usually entails doing something that will "probably always be ok". Doing stuff like that repeatedly adds up to frequent issues.


> I generally look at a given benchmark there

Which? Just curious.

Some-of the spectral-norm programs seem quite similar:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...


Hi! Thanks for the update! I usually look at your curated list of "idiomatic/optimized/non-portable and unsafe" but in the list you noted the c# solutions faster than go had intrinsics.


Those benchmarks were debunked, they don't represent anything.


Where were they "debunked" ? Please share.


You just need to look at the c# implementation.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: