4 ms·
I agree that null pointers have never been this huge problem compared to many others. But I think it is rather convenient to formally specify which pointers ca
by fauigerzigerk 10mo ago
I agree that null pointers have never been this huge problem compared to many others.
But I think it is rather convenient to formally specify which pointers can be null and which ones can not.
How do I tell the users of my library wether they can pass null into my API? How do I stop people from putting "just in case" null checks into code that doesn't need it, obscuring the logic of the program and burdening callers with yet more error handling?
In my opinion, the "modern" approach of using some sort of Maybe type is just far more productive.
- ant6n 10mo agoDidn’t c++ solve this problem with references vs pointers? References shouldn’t be null, pointers could be.
- mojuba 10mo agoIt didn't make pointers safer to use though. In Swift and some other modern languages you can't dereference an optional (nullable) pointer without force-unwrapping it.
- amelius 10mo agoYou can still fabricate a null reference IIRC.
- Rexxar 10mo agoIt always involve an undefined behaviour at creation of the 'null reference', there is no legal way to create it.
- amelius 10mo agoTrue. In any case references solve only half of the problem because it lets you state "this function will not take a null pointer". You still cannot say "this function may take a null pointer" unless you use a very unusual convention of saying that any pointer argument may take a null pointer.
- widdershins 10mo agoI don't find that convention unusual. That's how I (and everyone at my company) writes code every day. If an argument is a pointer, that means it may be null. If it may not be null, it should be a reference.
- amelius 10mo agoAnd the libraries that you use? E.g., std::size_t std::strlen(const char* str);
- PaulHoule 10mo agoIt's a really common pattern that you want to write Object value = a.b.c.d; for something like a JSON value you got over the web where any of it might be null but have to write something like Object value = nonNull(a) ? nonNull(a.b) ? nonNull(a.b.c) ? d : null : null : null or Object value = null try { value = a.b.c.d } catch(NullPointerException x) {} Just being able to write something like const value = a?.b?.c?.d; is a great relief. If it is just value lookup letting a.b return null if a is null would be fine with me but there is something a little creepy about a.doSomething() doing nothing and returning null in that case. Personally I am not a fan of Optional<T> and (worse) Either<A,B> in Java for various reasons. I think the official functional stuff in Java (like the streams API) is awful, but I like working with functions like Object value = nullSafe(a,x=>x.b,x=>x.c,x=>x.d) The author has some affinity towards a collection-first or collection-only style of programming and certainly I have written programs or subprograms working with dynamic structures that leaned heavily into List<T>, that is, a value which might be present or absent can be treated as a List which just happens to have 0..1 members and x.map(y=>...) and other functional operators do the right thing for the 0..1 and 0..N cases and if you use the same set of operators for both of those cases they just roll off your fingers and you are less likely to forget to put in null checks and when you compose more complex operators out of simpler ones it tends to "just work"
- tekne 10mo agoMy personal preference would be to have separate types `A` and `A?` and overload field projections to work on `A?` as you'd expect. Subtyping optional. Putting on my theory hat, while we we can overload field projection for any monad (data structure representing a result + an effect : think result for exceptions, or a thunk for a promise), it's not the best idea. But for what is at least morally a commutative (order doesn't matter: FAIL ; pure = pure ; FAIL = FAIL) and idempotent (FAIL ; FAIL = FAIL) monad, it works... Which justifies fun things, like lazy projections on promises!
- PaulHoule 10mo ago... or maybe in the definition of type A you can specify what ((A) null).someValue or ((A) null).doSomething() does at the field or method level. I guess there is the issue of how you figure out what the type is which depends of course on the language. Could be a better fit for C++ than all-virtual Java but I don't want to give the C++ any ideas to make that language more complex!
- onionisafruit 10mo agoA function argument might be a pointer for a few reasons. Is it optional? Is it to avoid copying a huge value? Is it so it can be mutated? Or, my favorite reason, maybe the function was written to be called by another function that happens to already have that value as a pointer. So yes, I wish there was a commonly used way to express which of these properties of a pointer will be exploited by the function.
- 01HNNWZ0MV43FF 10mo agoC is such a Blub language lol Optional is `Option<T>` Zero-copy is `&T` Mutation is `&mut T` Diehard C programmers have Stockholm Syndrome for the language because they like to show off how they can be productive in a bad language. If they took a few months to learn C++ / Rust / C# / any language that has solved this, they'd have to admit that they staked a lot of their ego on a language that constantly makes them jump through hoops. Because they love showing that they're good hoop-jumpers. But any noobie who's a year into programming will say "Oh cool, in those languages I don't have null pointer exceptions" and never learn C. Good!
- alfiedotwtf 10mo agoIf only I had a dollar for every time I’ve heard “you just need a different mindset” and “you just to be better at C” as an excuse as to why “we don’t need rust”, it’s always been from the same people who have CVEs against their own C code failing to do exactly what at they say they could never do in real C code
- rwmj 10mo agoWhile the "modern" (actually, 1970s, from ML) approach with option types is vastly superior, modern C compilers do let you declare that function parameters should not be NULL. In GCC or Clang, add __attribute__((nonnull)). There are still issues[1] with this, but it's sufficient for most code. [1] One big issue is that GCC takes this hint and uses it in the optimizer, so you cannot have both a compile time and a run time check for a non-NULL parameter.
- jedwards1211 10mo agoAfter using TypeScript I see userland Maybe types as a workaround for a language design flaw. When the builtin type system allows you to declare nullable and non-nullable reference types and produces compile errors when you don’t check a nullable value before dereferencing it, the problems with null go away
- yencabulator 10mo agoOption<Option<T>> works fine, T | undefined | undefined doesn't. Typescript does weird things because they wanted to make it backwards compatible with Javascript.