DIP 1017--Add Bottom Type--Final Review

Johannes Loher johannesloher at fg4f.de
Fri Jan 18 00:32:08 UTC 2019


Am 18.01.19 um 01:17 schrieb H. S. Teoh:
> 
> Well, void* is simply a bad name for Any*, where Any is the top type.
> Even if we fix void* by renaming it to Any* (so that `void*` actually
> means a pointer to a unit type, whatever we decide that would be), we
> still have the problem of the chain of implicit conversions:
> 
> 	void --> TBottom* --> Any*
> 
> so as long as you define void == TBottom*, you have the weirdness:
> 
> 	void procedure(...) {}
> 	Any* ptr = procedure();
> 	// subsequent fun with casting and dereferencing ptr.
> 
> This is why I don't think we should define void == TBottom*, even though
> both are ostensibly unit types.  Besides, following the same logic, one
> would have to conclude typeof(null) == void too (since typeof(null) also
> only contains a single value), which leads to other weird situations.

I actually think this is ok. I don't reall have an issue with it. But I
am also not convinced that we _need_ to do it that way. As I mentioned
ealier, Kotlin for example does not do this (you have to replace
pointers with optional types). They have distinct `Unit` and `Nothing?`
types and this is fine in my opinion.

On the other hand, I definitely think we should make `Tbottom* ==
typeof(null)`.

>
> Anyway, you brought up an excellent point that D's types are not
> structural types. So perhaps pointers, including TBottom*, aren't as
> simple as we thought they were.  Perhaps we could analyze pointers as
> having an implicit (and unrepresented) component identifying themselves
> as a pointer type, in addition to holding the pointer value itself. If
> you will, they're a product type of an atomic isPointer object with the
> pointer value to their specified type.  So TBottom* isn't the same as
> the real unit type, which conveys no information; it (implicitly)
> conveys the information that it is a pointer, so it may be distinguished
> from the unit type as being the product of isPointer with Unit, not just
> Unit itself.
> 
> Then we can still define void as the unit type, and TBottom* would be a
> distinct type that always has the (explicit) value null (with an
> associated implicit isPointer attribute).  Dereferencing TBottom* would
> then be identical to dereferencing null, which should cause a runtime
> abort.
> 
> (And similarly, empty structs would not be true unit types either, but
> product types of their names with the types of their fields. True
> product types in the type theoretic sense would have to be anonymous
> structs or entities like std.typecons.Tuple.)
> 
> Or alternatively, we can think of TBottom* as a *decorated* type
> (decorated with isPointer or TBottom as the type of its target) that is
> to be distinguished from the (undecorated) true unit type. Similarly
> with named empty structs.
> 
> 
> T
> 

This sounds very reasonable.



More information about the Digitalmars-d mailing list