Sum Types - first draft

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Tue Sep 10 18:03:32 UTC 2024


On 11/09/2024 5:23 AM, Paul Backus wrote:
> On Tuesday, 10 September 2024 at 17:05:49 UTC, Walter Bright wrote:
>> Thanks for your detailed response. Let me address just one for the 
>> moment:
>>
>> On 9/10/2024 9:20 AM, Paul Backus wrote:
>>>> * std.sumtype cannot optimize the tag out of existence, for example, 
>>>> when having:
>>>>
>>>>       enum Option { None, int* Ptr }
>>>
>>> A built-in sum type would not be able to do this either, because in 
>>> D, every possible sequence of 4 bytes is a potentially-valid int* value.
>>>
>>> The reason Rust is able to perform this optimization is that Rust has 
>>> non-nullable reference types [2]. If D had non-nullable pointer 
>>> types, then std.sumtype could perform the same optimization using 
>>> reflection and `static if`.
>>
>> I was approaching it from the other way around. Isn't a non-nullable 
>> pointer a sumtype? Why have both non-nullable types and sumtypes?
> 
> You have it exactly backwards. A _nullable_ pointer type is the sum of a 
> non-nullable pointer type and typeof(null).
> 
> A non-nullable pointer type is a pointer type with its range of valid 
> values restricted. You could think of it as a "difference type"--if you 
> take T*, and _subtract_ typeof(null) from it (i.e., take the set 
> difference [1] of their values), you get a non-nullable pointer type.
> 
> [1] 
> https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement

Yes, Paul is correct.

A non-null pointer is guaranteed by the compiler (at compile time), that 
it may ONLY point to a valid value that is directly usable.

A nullable pointer replaces guarantees for UNCERTAINTY.

It could point to unmapped memory (i.e. null), junk, or something 
completely different. The only guarantee is that the pointer itself 
exists, what it holds is entirely unknown.

To resolve this you introduce type state analysis to make guarantees of 
non-null. Which I have wanted for quite a while now. The amount of 
uncertainty for pointers in D right now are not good enough if you want 
to guarantee memory safety.

An interesting paper on this subject is [Blame for 
Null](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2020.3).

It reviews a number of languages, and proves using lambda calculus that 
only nullable pointers can introduce runtime errors (null dereferencing).

Of note is that sum types are only discussed as an implementation detail 
of Scala.

"
Keeping λnull simple. We could reduce the number of function types and 
avoid the need for safe applications through a combination of sum types 
and case analysis. For example, in Scala nullable values are represented 
with sum types (e.g. a nullable string has type String | Null). The case 
analysis in turn requires support for flow-typing:
"




More information about the dip.development mailing list