Hacker News new | ask | show | jobs
by gambler 2817 days ago
>.NET is still very popular but it definitely did not fulfill the more ambitious dreams that Bill Gates had for it.

There is still time. It just recently got open-sourced, got a compiler written in itself and got a run-time unbundled form all the legacy crap. Those things held C#/.NET back. I feel this is a good time to adopt it for people who want to have reasonable performance, static typing and a mix of OOP/functional paradigms.

My two notes on C#:

1. It is possible to write reasonably "functional" applications in .NET. The only problem I had with that is lack of built-in copy-on-write data types and prevalent nullity.

2. LINQPad is the best damn scripting environment I ever worked with.

3 comments

> 1. It is possible to write reasonably "functional" applications in .NET. The only problem I had with that is lack of built-in copy-on-write data types and prevalent nullity.

I've tried to minmise that pain over the past few years with my 'functional language extensions' for C# [1].

It's a library with most of the common monadic types (as structs so there's no null issues); Immutable collection types that don't have an unweildy naming scheme like like the System.Immutable.Collections library - which are all structs, so no nulls; A type called 'Record<T>' which when you derive a type from it gives your type value-semantics (equality, ordering, GetHashCode, ToString, serialisation/deserialisation) by default; and tons more.

You still have to do stuff like build your own With method for immutable types. I have written of how these can be achieved _realtively_ easily [2]

C# has made great strides over the past 10 years to make it easier for those of us that want to work functionally to do it. It still has some way to go (discriminated unions, higher-kinds, record types, etc.) but it's already possible to write code functionally - you just need to do some boilerplate every now and then.

[1] https://github.com/louthy/language-ext

[2] https://stackoverflow.com/questions/38575646/general-purpose...

Wow, what a nice project you have there.

I've read that the next C# will have non-nullable reference types, have you thought about how to make your framework fit in with that? It's a "natural" Some/None in a way.

> Wow, what a nice project you have there.

Thanks :)

> It's a "natural" Some/None in a way.

If we lived in the perfect non-nullable reference world from the start then it's arguable whether Option<A> would ever have been needed - and so going forward it should be needed less, or not at all for some devs. The question comes when you need an optional value, and so you use nullable references instead of Option<A>. With nullable references the `null` still honours the contract of `A` - this is what Option<A> protects against. If the flow-analysis for nullable references is good enough to spot that you're possibly going to use null and then forces you to use a predicate of some sort (if/switch/ternary/...) to validate the referenced value exists then I think we're good. I understand that is what's planned, but it needs to be bulletproof.

There will be devs working in the nullable reference world for a long time (due to difficulties with moving to the new world when it comes) - and so I fully expect Option to be useful for its null protection reasons for a long time.

The story is a bit bigger than just protection against null though. If instead of seeing Option<A> as A|null, you see it as A|B, where B is the single-value type: Unit. Then Option is A|Unit. If you then look at Either<L, R> which is designed to represent one of two alternative values: L|R then it's pretty easy to see that Option is Either<Unit, A>. And then when we look at Try<A> which is designed to return A or capture an exception and return it as a value, then that can be seen as Either<Exception, A>...

All of the types that represent one of two values have lots of additional powerful functionality: Fold, Map, Bind, BiFold, BiMap, BiBind, etc. and have been designed to seamlessly switch between each, which won't exist on the standard nullable reference types. So, there's still a place for Option in the bigger scheme of things.

Personally, I can't wait for non-nullable references to come in. I built language-ext to try and get a handle on a 10,000,000+ line code base that kept falling foul to null reference exceptions (along with other common C# coding world problems). It was 100% to help me and my team build more robust code. Non-nullable references is a feature we will turn on immediately, even if it takes a week to fix up the warnings and errors it spits out, this is going to be one of the most important updates the C# team have done.

Part of me, though, worries that the ship has sailed. For a while .NET was probably completely fine from Microsoft's perspective, because the platform was (AFAICT) dominant in their target market of enterprise apps.

Then big data became a thing, and basically the entire core ecosystem was written in Java. I think it's becoming a bit of a wedge issue - Java has everything that .NET has, but .NET does not have its own equivalent of, for example, the Hadoop ecosystem.

You can do "big data" entirely in .NET.

You can use Hadoop "Streaming" with .NET easily enough and still take advantage of the "Hadoop ecosystem".

Orleans is not exactly Hadoop, but it's close enough that conversions between are relatively straight-forward, and Orleans is useful for a number of other work distribution patterns beyond map/reduce.

Beyond that, the map/reduce pattern is one of the easiest abstractions to reimplement yourself from scratch if you get the itch. I believe Hadoop is relatively over-rated from that standpoint, and arguably IMO another case of Java developers over-ceremonializing what should be a simple, lovely abstraction/design pattern into a weird spaghetti mess of configuration and ritual.

> Java has everything that .NET has

Java offers nothing for game developers, there're multiple game engines written in .NET or using .NET. Java only runs on Android, .NET on all mobiles. Native interop in Java is a joke.

Actually Java had jMonkey and LibGDX before Unity became the engine it is today. Which initially was Mac only and only used Boo and Unity Script as programming languages.

Khronos does have some official OpenGL specs for Java. There are none from them for .NET.

Java runs on iOS via Codename One and Gluon AOT compilers.

Native interop in Java was made hard on purpose, as Sun was pushing for WORA. Oracle is in the process of improving the situation with Project Valhala.

I love both stacks, truth is that .NET still has a bit to catch up outside Windows, while Java lost a bit of its mojo on desktops.

About games, maybe the reason is lack of value types in Java which stresses GC and creates pauses. .NET works OK, Unity is the most obvious (cities skylines, kerbal space program, etc.), but also XNA, MonoGame, SharpDX. This creates an ecosystem with healthy amount of libraries and other resources.

About native interop, I know Java did it on purpose, but as a developer I don’t care much about the rationale. I’ve heard about upcoming Valhala years ago (announced in 2014), still not ready.

Related to both of them, .NET core 2.1 already has SIMD support. Some parts of it is experimental, but it already works more or less OK, esp. on Intel/Amd.

Java had such eco systems first with Java3D, JOGL, Khronos OpenGL bindings, 3D for J2ME, jMonkey, LWJGL

Problem was that Sun never was too serious about their Java Gamming initiative.

Unity only adopted C# after moving out of the Mac into the PC, and it was stuck for ages in 3.5 as they didn't want to pay for the new licenses. Which meant it grew to a kind of C# dialect, which is being fixed now.

ManagedDX and XNA were Quixotic projects not well seen by WinDev. Which replaced XNA with DirectXTK when given the opportunity.

Which took a couple of years effort until Microsoft acknowledged the work done by the MonoGame guys.

Things take ages in Java because there are multiple vendors and everyone has to contribute to the process.

Intel has provided SIMD auto vectorization improvements. There are a couple of talks about it.

> Unity only adopted C# after moving out of the Mac into the PC

Not quite true; Unity has always used Mono. The very first Unity 1.0 version in 2005 was already using C#/Mono.

> Which meant it grew to a kind of C# dialect

Unity never had it's own "C# dialect".

> truth is that .NET still has a bit to catch up outside Windows, while Java lost a bit of its mojo on desktops.

I agree, that's quite a nice summary of the 2 ecosystems

> Java has everything that .NET has

C# certainly has many features that Java, the language, does not. It gets better if you consider Kotlin instead, but it's not clear to me if that language has a chance of becoming on par with Java, popularity-wise.

LINQPad is awesome, and I'm always amazed to still find a lot of .NET developers who've never given it a try.

A cross platform version is high on my wish list.