Hacker News new | past | comments | ask | show | jobs | submit login

> Rust has a concept of null, though there are way more nulls in regular Java code than in regular Rust code: https://doc.rust-lang.org/std/ptr/fn.null.html.

I've used Rust for about 6 years now, and I don't think I've ever used ptr::null(), mainly because I don't really write low-level wrappers around C libraries. I'd argue Rust does not have null as a concept or language feature - ptr::null() is just a convenience function for creating a pointer with the value of zero. The point of not having null is that in most languages null can appear basically in any variable or value, while in Rust null pointers can only exist when writing very low level potentially memory unsafe code.

> If the issue is representing non-existence, Kotlin, C# and TypeScript (configured properly) all have nullable types.

They do indeed have nullable types, but at least in in C# and TypeScript (and probably in Kotlin because of JVM interop) non-nullability is basically a lint with zero runtime guarantees. That is often good enough, but it's still a far cry from an absolute 100% percent guarantee provided by not having nulls even as a concept. Having nulls is a problem you can't fix by adding features - you have to design the language and/or the runtime from scratch without them.

> There's a good chance you'll be more productive with those instead of Rust for regular backends

I'm not arguing against the productivity of these languages or demanding anyone writes anything in Rust. I mostly write TypeScript in my day job, and it is a practical and productive choice for the work we do (web frontends, backends and serverless services). I just want to inform people about the capabilities of Rust and correct misunderstandings.




> non-nullability is basically a lint with zero runtime guarantees

Heh? What else is it in Rust or any other language? Like, the only way I could imagine a null pointer exception leak into C#/JVM-language program that got statically analysed to not contain null is through some Reflection-based unsafe operation - at which point we can also talk about unsafe operations in Rust that just as well can cause “null-pointer exceptions”, except those will be hard memory failings (undefined behavior basically), potentially corrupting the whole execution.


In C# you can explicitly, in the language, basically say "Don't worry this won't be null" and the compiler takes your word for it and lets you do stuff that definitely isn't OK if it's null.

The language has to do this for two reasons. Firstly, this is a retro-fit, so if you don't have this you need to throw away all the old C# code, why not call the new language something else ? Secondly though, and perhaps more important to the C# ethos is you must allow null everywhere to be compatible with the Common Language Runtime. C# has to accept anything the CLR does at any function boundary. This means what can be promised is the lowest common denominator of all CLR languages which exist or are going to exist.

Suppose your C# code checks a string value called username is actually some string, by calling IsNullOrEmpty(). It'd be annoying if after doing that C# just insists username might be null anyway - you just checked! So, that function marks the string reference you called it on as definitely-not-null after having checked. However, you can just make a new function LOLWhatIsSafety() which just always returns 69 and marks the reference as definitely-not-null. In both cases the compiler just takes their work for it.


> In C# you can explicitly, in the language, basically say "Don't worry this won't be null" and the compiler takes your word for it and lets you do stuff that definitely isn't OK if it's null.

You can do this in Rust too. Unsafe Rust is still Rust.


You can, although they're pretty keen on discouraging you from pointing this particular gun at your feet, e.g. ptr.with_addr() can't achieve this on its own because it wants a NonZeroUsize, so first you need to make a NonZeroUsize that's actually zero. But yes, you can write that in unsafe Rust and now your program has Undefined Behaviour.

In contrast all the routes I suggested for C# aren't unsafe, aren't even flagged as "Be super careful here, dragons ahead" because the C# attitude is that every single C# function is responsible for explicitly doing its own null checks if they're needed.


You're right, idiomatic C# will have usually way more nulls than idiomatic Rust.


C#'s null safety is not sound. There are situations where even a fully annotated program without reflection, code generation, unsafe or other tricks will crash of a null pointer exception:

https://docs.microsoft.com/en-us/dotnet/csharp/nullable-refe...


I’m not familiar with C#, so I probably should not have included it. But Kotlin, Scala 3 (with a compiler flag) and even Java with static analysis should be sound, if I’m not mistaken.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: