4 ms·
The inventor of the null pointer considers them to be a mistake: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare http
by Decade 10y ago
The inventor of the null pointer considers them to be a mistake:
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare https://www.infoq.com/presentations/Null-References-The-Bill...
- twblalock 10y agoSo what? He's wrong.
- meddlepal 10y agoThat quote gets pulled out of thin air every time this argument comes up and it's pretty silly. I think more specifically, nullable by default might have been the bigger mistake not that null is inherently a mistake.
- twblalock 10y agoThe fact that most of these replies mention esoteric langiages that have no traction in industry kind of proves my point.
- junke 10y agoThe mistake is Null being a member of all (reference) types. This is not the case in all languages that have a nil value. In Common Lisp if you declare an argument to be a string, it is an error to pass NIL. You have to declare the type to be "(or string null)". That's exactly what the Option type provides.
- twblalock 10y agoThat is not how Lisp works. You are just wrong.
- deleted 10y ago[deleted]
- junke 10y ago> That is not how Lisp works. You are just wrong. Please tell me how it works, then. I guess you could easily find a counter-example. First things first. Optional arguments are handled by &OPTIONAL and &KEY parameters, which can be used to provide defaults values as well as a flag indicating whether the argument is provided. The most used default value is probably NIL. NIL belongs to the SYMBOL, NULL, LIST and BOOLEAN types and their supertypes (ATOM, SEQUENCE, T). If you really want, you can include it in a custom type too. For most uses, the type (OR NULL U) is regarded generally as an optional U. This is consistent with the definition of generalized boolean and lists (a list is an optional cons-cell). If some corner cases, you have to use another sentinel value or use the third binding in &OPTIONAL and &KEY argument bindings. This is hardly a problem if you have a type U such as (TYPEP NIL U), but for most useful cases, (TYPEP NIL U) in fact returns NIL. Here below I define a function FOO which accepts a string and prints it: (defun foo (x) (print x)) The type declaration for FOO is: (declaim (ftype (function (string) t) foo)) In Java, such a function will works with null too, because null is an acceptable value for String. In Common Lisp, you have to write this declaration to allow NIL: (declaim (ftype (function (or null string) t) bar)) And just to test how it behaves, let's use IGNORE-ERRORS to catch errors and return them as secondary values. Calling the first FOO with NIL signals an error: (ignore-errors (foo nil)) NIL #<TYPE-ERROR expected-type: STRING datum: NIL> ;; Does not print anything else The same test case with the second FOO shows that it accepts NIL: (ignore-errors (foo nil)) NIL ;; prints "NIL" Lisp being Lisp, those checks are likely to be done dynamically, but in some cases, your compiler can determine if a variable will hold NIL and warn you about a conflicting usage. However, how type checks are enforced does not change the argument, namely that NIL is not an appropriate value for all types.
- twblalock 10y agoHere is my counter-example. It is the console output of Clisp 2.49: Break 1 [2]> (declaim (ftype (function (string) t) foo)) NIL Break 1 [2]> (defun foo (x) (print x)) FOO Break 1 [2]> (foo "hello") "hello" "hello" Break 1 [2]> (foo nil) NIL NIL Break 1 [2]> There were no errors. The function accepted nil and printed it. You must have some other type restrictions going on than what you mentioned. The output is the same whether I put the declaim statement before or after defun foo.