5 ms·
"Making everything a reference: The Billion Dollar Mistake" is the talk I want to see
by seventh-chord 7y ago
"Making everything a reference: The Billion Dollar Mistake" is the talk I want to see
- x3ro 7y agoCan you elaborate? I can't remember the last time I thought "oh darn it why is this a reference", but I can think of a billion problems I've had with nulls in jvm languages
- emsy 7y agoCache incoherency, which will cost us more and more performance as CPUs will improve slower in the future.
- gameswithgo 7y agothere are a few completely different ways to interpret this, can you explain?
- seventh-chord 7y agoin languages like c, rust or go, where you can put arbitrary data on the stack, it seems to me as if such issues are less common because you dont have to worry about initializing pointers and allocating memory unless you actually want to put something on the heap. Thus if you make everything a reference in your language its no wonder you run into issues like null-pointers more often
- DaiPlusPlus 7y agoWith stack allocation you then encounter problems with object lifetime. Rust solves this problem by binding references to scope, and Go solves this by invisibility changing an allocation to the heap (and uses ref-counting? I think?). I wish C had a feature that would let you allocate something on the stack and then return to the parent stack frame without popping the stack-pointer - that would be handy for self-contained object-constructors.
- cm2187 7y agoPlus also doesn’t the stack need to be small to fit into the CPU cache?
- seventh-chord 7y agoThere is absolutely no requirement from the hardware that the stack be any particular size
- DaiPlusPlus 7y agoOn the Windows desktop, the default stack size is 1MB. In IIS-hosted applications the default stack size is reduced to 250KB due to the popularity of the now-outdated programming trope of "one thread per request (per-connection)". On x86 Linux the default stack size is 2MB - which seems generous.
- cm2187 7y agoI am not thinking requirement by rather performance wise.
- kragen 7y agoIf you start allocating multi-kilobyte objects in your stack frames, they are not going to fit into L1.
- zozbot234 7y agoGo uses fully-general GC, not reference counting. Obligate reference counting is used in other languages such as Swift, probably with worse throughput than obligate tracing GC.
- giulianob 7y agoRegardless of whether it's on the stack or heap the point still stands. If all your objects are randomly allocated then an array is just references to those objects and will start out null. If you're using value types then your array of objects will never be null (empty instead) and you will benefit from CPU caching the data.
- dorfsmay 7y agoEverything in Python is a reference, and there's no null pointer issues.
- auxym 7y agoI've certainly had some "None" errors in Python. I think the difference comes from dynamic vs static typing. In Python, you sort of get into the habit of "defensive" programming: checking inputs to your function, catching Nones, etc. In java, you tend to rely more on the type system. If it typechecks/compiles, there's a good chance it's OK. That is, until you get a null value that's not handled. That's the root issue I think: If null is an acceptable value per the type, then the same type system should force you to handle it. As do the type systems in ML languages for option types, for example.
- JakobProgsch 7y agoThe first line is why I'm not 100% convinced of the severity of this mistake compared to the alternatives. The problem fundamentally is the use of magic values/numbers to represent the concept of "no value". You don't need explicit language support to have that concept and the bugs it causes. I guess having that as an intrinsic concept in the language makes it more likely that people use it badly. On the other hand debuggers etc. also intrinsically understand this and segfaults due to null pointers are usually very easy to localize once you see them. On the other hand if a "bad programmer" introduced their own magic non-value in a supposedly safe language, debugging that becomes way more confusing.
- andrepd 7y agoNo, that's not the "fundamental problem". The fundamental problem is a type system that lies. A "pointer to string" is not actually a pointer to a string, it's a pointer to a string or to nothing. If your api returns a pointer of the latter type, it should signal this by making the return type "maybe-pointer to string" (although it has the same memory representation as "pointer to string"). Then, if the user tries to dereference a maybe-pointer (that is, to use a maybe-pointer as a pointer), the type system can statically catch this and make it a simple type check failure compilation error. The user must first check if it's null through a function that casts a maybe-pointer to a pointer. Nothing about this precludes the usage of sentinel values.
- kragen 7y agoYou may be interested in http://canonical.org/~kragen/memory-models http://canonical.org/~kragen/memory-models then. I don't think it's necessarily a mistake but it's definitely taken for granted far too much.