I know that in C# it isn’t, and it is in languages like Haskell (if I am not wrong), so thought maybe F# also had the same semantics by default.
Also even though it doesn’t exist in C#, it’s a limitation of the language not the runtime, right? Like either F# or some other new .NET language can in fact implement this as a default without using any sort of hack.
In F#, if you define a new class or other type in F# code, then it will be non-nullable by default, in the sense that e.g.
However it compiles down to .NET IL code as a class, which is a reference type on .NET, which can be null, and thus either C# could create nulls of that type, or even in F#
would give you a null. So in that sense, it is very much a “limitation of the runtime” – you can never create a .NET language that can both “expose a class to C# so that it looks like a normal class” and also “ensure that instances of that type are never null”. So you always have to make pragmatic decisions here. F# tries to prevent you from accidents and the annoyance of dealing with null when you stay inside F#, but if you deal with interop or .NET runtime details, at the end of the day null is always hanging around. (Billion dollar mistake.)