Meyer makes an important point that often gets lost: the null pointer predates Hoare. NIL existed in McCarthy's Lisp in 1959, six years before Hoare added null references to ALGOL W. The "mistake," if it was one, was already widespread.
What made Hoare's 2009 confession so impactful wasn't that he was solely responsible — it's that he was the first person with that level of authority to publicly say "this was wrong."
That's what gave Rust, Swift, and Kotlin permission to design around it.
I don’t know much about algol, but in Lisp, nil represents the empty list. And because the list is a recursive data structure, it always contains the empty list. It’s not the same as java where null is its own value that is part of every type. In Lisp, an atom can’t be nil because an atom is not a list.
LISP was special because it had only 2 data types: atoms and lists.
Both lists and atoms could appear in any place in any function or special form.
NIL was a special atom, which was used to stand for an empty list. Because it could appear in any place in a LISP program, it could be used anywhere where one had to write that something does not exist.
In a programming language with a more complicated and also extensible system of data types the handling of "nothing" values must also be more complex.
Any optional type can be viewed as a variable-length array of its base type, whose maximum length is 1 and a null length indicates a non-existent value.
This is equivalent with the use of NIL in LISP.
However, it is better to consider optional types as a distinct method of deriving types from base types than arrays, structures or unions, because in most cases more efficient implementations are possible for optional types than implementing them as variable-length arrays that may have a null length or as tagged unions where one of the alternative types is the empty set (a.k.a. void).