• Subject: Re: Idea. Removing nils from the language.
• From: Enrique Arizón Benito <enrique.arizonbenito@...>
• Date: Sat, 10 Jan 2015 18:09:49 +0100

Hi Dirk, Scott, Hao Wu, "All"

> It seems appropriate to read `always` as a synonym for `IMHO`.

The "always" was not expressing an "IMHO", but actually a mathematical fact. But since mathematical facts must be probed, let's probe it! (mathematics is what makes of programming a science vs an art)

- Suppose we have an algorithm consisting of a set of input values, some code processing the value and a final set of output values. Let's probe the next statement:

"nil values can always be replaced in the processing code"

- To probe that the previous statement is >>always<< true I will show that the opposite statement is >>always<< false:

"nil values can NOT always be replaced".

- If "nil" values can NOT be replaced there are certain algorithms that need a "nil" to complete.

- "nil" can not be read, but just compared, and so it can only appear inside conditional comparisons similar to:

if myVar == nil then ... end

- The result of this comparison is always true if myVar is nil or false if myVar is not nil.

- There exists many different combinations of values that can be used to obtain a similar behavior replacing the nil. For example we can use the integer 0 or the string "0" to create a similar algebra.

if myVar == 0 then ... end
if myVar == "0" then ... end

- That probes that our previous statement "nil values can NOT always be replaced" is false, and so the opposite "nil values can always be replaced" is true.

> "you may end up replacing nil with explicit type-specific sentinel values or option types that have similar semantics."

You are completely and absolutely right! The problem with nil is that there are two scenarios in which comparing a variable with nil can be true.
- The first one is that we, ON PURPOSE, have set that variable to nil as a sentinel value. This is correct. No problem with it.
- The second one is that we, BY MISTAKE, have forgot to initialize the variable and just declared it. This is part of the "billion dolar mistake", as Tony Hoare named it.

> "the immediate reaction from my head is how you would approach this?

> local foo
> local bar = function() foo = 1 end
> bar()
> print(foo)"

Thanks for this question since it makes it clear why nil is so dangerous. The simple solution is:

local bar = function()
local result=1
return result
end
local foo = bar()

Removing nil forces to provide a value at variable declaration, so the line "local foo" is not valid anymore. Since the algorithm used to initialize the variable is in bar, we just change the API for bar to return the result that will be used to initialize foo.
Imagine that we are working with a complex 10k lines of code and later on we have some code looking like:

if foo == nil then
remove_My_Back_Account()
else
I_won_the_lottery()
end

With the first version of the code (nil allowed), if we forgot by mistake to invoke bar() we will be much poorer now :( .
In the second version of the code, If we remove the nil, we are forced to initialize foo before using it. If we forget to execute " foo  = bar()" the line "if foo == nil" will fail with an error similar to   "foo is undefined".
A very illustrative example of the billion-dolar-mistake.

I will try to find some time to create a nil-free implementation based on the existing code, and publish it on GitHub. Anyone curious is welcome to participate. Since I don't have much free time I can not promise anything in the coming month/s.

Regards!
Enrique

P.S.:
(Sorry if I do not reply to all your comments, but I don't have time enough to do it, even if some are really interesting)

On Fri, Jan 9, 2015 at 10:17 PM, Dirk Laurie wrote:
2015-01-09 22:44 GMT+02:00 Enrique Arizón Benito
<enrique.arizonbenito@gmail.com>:

But given that Lua is a dynamically typed language, the concept
of a value that is so nonexistent that it does not even have a type
is a very useful abstraction.