No reason why you can’t experiment as you see fit, but this would depart from what makes a dynamically typed scripting language useful (i.e. parsimonious and flexible) for me.
You can certainly remove the notion of a generic nil to mitigate typing errors, but in a lot of real world (note not “all") cases you may end up replacing nil with explicit type-specific sentinel values or option types that have similar semantics. For example replacing
nullable_list ::= nil | list_element list
list ::= empty_list | list_element list
does that. We will no longer confuse an empty list with a variable of another type which is inadvertently set to nil.
However even an option type or sentinel still gives as a “variable that can not even be read” except by understanding that it represents an empty list but it is not more complex than enforcing nullability by strict normalisation of active variables by scope (which is what I presume you mean by “not possible to have nil errors”, and is easier for program analysis.
But we’ve left behind dynamic typing or implemented a static typing system on top of a dynamic typing system at this point, or required that we normalise code blocks depending on what non-nullable variables they require, which again for my use cases (note not necessarily yours) would make things quite verbose.
I couldn’t really disagree more with this - in the most general case of an array.indexof method, for example, not found can be (note not "always is") an expected result not an exception case, and a generic library probably has some form of that call which indicates this case with an explicit option type, or a success/failure return which has the same effect as an option type, or by a sentinel value (representing a non-reference) which requires comparison specific to the type (and possibly the container instance). You will still have errors if you don’t handle those correctly, and if you do use exceptions, you are simply allowing the error to propagate to a potentially unrelated part of the program but at runtime (note not necessarily in your test cases).There may be a particular implementation for which “not found” violates an assertion which should be true and of course an exception may be suitable then.
You should also look more closely at languages like C - the “null pointer” constant need not translate to a literal pointer value of 0 even if it often does. It’s not really helpful to compare an abstract description of one language geared towards certain things with mere facts about implementations of other languages that are decidedly targeted at different problems.