Bottom Type--Type Theory

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Jan 17 13:15:03 UTC 2019


On Thu, Jan 17, 2019 at 10:35:00AM +0000, Dukc via Digitalmars-d wrote:
[...]
> I think `void` can still be saved. I'm not sure about the meaning of
> "bottom" and "top" types, but I think that with a few non-breaking
> changes, it can be made to logically be the polar opposite of
> typeof(assert(0)):
> 
> -Where any type would be convertible to `typeof(assert(0))`, no type
> is convertible to `void`.
> -Where no type is convertible from `typeof(assert(0))`, any type could
> be made convertible from `void`, the only possible value of void
> converting to target type's `.init` value.

I think you got the conversion direction mixed up.  If typeof(assert(0))
is supposed to be the bottom type, then it must implicitly convert to
every other type (as Walter's DIP stipulates), but no other type could
implicitly convert to it.


> -Where a pointer to `typeof(assert(0))` can point to nothing, a
> pointer to `void` can point to anything.

This is inconsistent with void being a unit type.  A pointer to a unit
type can only ever point to the unique value of that type, it cannot
point to anything else.

This is where changing void to be a unit type will break every code that
uses void*.  Basically, void* is a misnomer inherited from C. It really
means any*, where 'any' is the universal type (i.e. the top type). But
because C has no such concept as a universal type, the void keyword was
contextually redefined to mean 'any' when a pointer type is made from
it. It's an unfortunate inconsistency analogous to saying that "one"
means "one" when it's a return type, but "one" means "infinity" when you
make a pointer from it.  It doesn't make sense as a whole, even though
contextually we've come to learn to read void* as any* even though void
without the * means something else.

Do not confuse a unit type with the top type. They are very different
beasts.


> -Where `typeof(assert(0))`, being capable of representing any type
> possible without loss of information, would have infinite size (and
> thus be impossible), `sizeof(void) == 0`, so it is possible even in
> systems with no memory at all.

I think you're confusing the bottom type with the top type here. :-)
The bottom type has *no* values; it's the unique type that cannot
represent *anything*. There can be no variables of this type, not
because its values are too big, but because it has no values at all.

A type that can represent any type is the top type, and it does not
require infinite space: std.variant.Variant, for example, can be
considered a top type, because it can hold values of any type. It does
not require infinite space.


> -`void` variables should be valid syntax, that can be assigned (no-op
> at machine level) and compared (lowered to literal `true` by compiler)
> to each other.
> -Compiler would be free to decide any non-null address for a void
> variable.  Since dereferencing a pointer to void will only result in
> void, which never uses any memory, it cannot do any harm.

Uhm, a random non-null pointer value can do *lots* of harm, because
being a systems language, D lets you cast pointers of one type to a
pointer of a different type. Casting a pointer to void to a pointer to
int, for example, will let you write to a random memory location. Very
dangerous.


T

-- 
Democracy: The triumph of popularity over principle. -- C.Bond


More information about the Digitalmars-d mailing list