DIP 1017--Add Bottom Type--Final Review

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Jan 17 22:33:35 UTC 2019


On Thu, Jan 17, 2019 at 09:43:52PM +0000, Jonathan Marler via Digitalmars-d wrote:
> On Thursday, 17 January 2019 at 20:15:20 UTC, H. S. Teoh wrote:
> > On Thu, Jan 17, 2019 at 06:51:13PM +0000, Jonathan Marler via
> > Digitalmars-d wrote: [...]
> > > To summarize, the bottom type allows you to declare a special
> > > pointer with no storage!
> > > 
> > >     TBottom*.sizeof == 0
> > > 
> > > This is also something that should be in the DIP and Walter should
> > > chime in with whether or not he thinks these semantics can
> > > actually be implemented.
> > 
> > This would introduce an asymmetry with the rest of the pointer types
> > in the language which all have equal sizes, and this asymmetry will
> > percolate down to other language constructs, causing special cases
> > and inconsistencies everywhere.  I don't recommend doing this.
> 
> Yes that's kind of the point :)  It's a new pointer type that has a
> unique size from all other pointer types.  This means you can
> no-longer assume all pointers types are the same size, you have a
> special case where it's size can be zero. This might warrant some code
> changes to handle this case, but does enable some new semantics which
> can be useful for library writers.  Case in point was you can now have
> a template parameter T* that the user can instantiate in such a way as
> to eliminate the pointer alltogether.

No, that's backwards.  (1) Introducing asymmetry, i.e., special cases,
is bad, because inevitably people will forget to check for it, leading
to endless bugs. It will also percolate all over the language, creating
exceptions and new corner cases, which are what we're trying to *reduce*
here. (2) Eliminating a field is achieved by passing in a Unit type, not
a Bottom type. E.g., if you have a struct template:

	struct S(T, U) {
		T t;
		U u;
	}

then you could instantiate a single-field struct by doing:

	S!(Unit, int) s;
	// Equivalent to: struct { int u; }

or:

	S!(string, Unit) t;
	// Equivalent to: struct { string t; }

Instantiating it with Bottom means forcing a compile error (or runtime
abort).


> > A better approach might be to make TBottom* always equal to null --
> > i.e., it's always illegal to dereference it because no instances of
> > TBottom can exist.
> > 
> 
> That's conceptually the same thing.  Saying that TBottom* is "always
> equal to null" is the same as saying it's a Unit Type, which is the
> same as saying that it contains no information so the storage needed
> is 0 (same as void).

I'm not so sure about that.  A true Unit type conveys no information,
yet TBottom* conveys at least this information: that it's a pointer, and
that the pointer cannot be dereferenced.  A true Unit type would be the
return type of a void function; would you equate TBottom* with the
return type of a void function?  That would be very strange indeed.


T

-- 
Freedom of speech: the whole world has no right *not* to hear my spouting off!


More information about the Digitalmars-d mailing list