proposed @noreturn attribute

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Tue Jul 18 08:26:59 PDT 2017


On 18.07.2017 14:19, Stefan Koch wrote:
> On Tuesday, 18 July 2017 at 12:15:06 UTC, Timon Gehr wrote:
>> On 18.07.2017 12:17, John Colvin wrote:
>>>
>>> Better to just not define it.
>>
>> That's not an option. Bottom is a subtype of all types. It cannot 
>> remove members, even static ones.
> 
> Timon, how important is it to actually have bottom ?

D has a C-inspired first-order type system, so it is not necessarily 
crucial to have it in D. (The reason I got involved in this thread is 
that it was proposed to add Bottom as a type that is not really a type; 
'void' is annoying enough as the 'null' of types. We don't really need 
another one of those.)

Bottom is the most principled way to encode noreturn (but the D type 
system does not have a tradition of being very principled, so 
introducing it has a cost that does not really exist the same way in 
more orthogonal designs: it falls out of them naturally).

If you have a very expressive type system, it is important to have empty 
types, because there you cannot actually decide algorithmically whether 
any given type is in fact empty. Another reason why one might want an 
empty type is that it is the neutral element for disjoint union (up to 
isomorphism). (But D does not have those built-in.)

> ... and what does it actually represent ?

It's a type that has no instances. If I say

int foo();

this means foo returns one of {0,1,-1,2,-2,3,-3,...,int.max,int.min}.

If I say

Bottom foo();

this means foo returns one of {}.

I.e., there is no value which foo might return. Hence it cannot return.

It can be argued that it is a bit silly to say:

int foo()@noreturn;

I.e., this function returns one of 
{0,1,-1,2,-2,3,-3,...,int.max,int.min}, but actually, it does not return 
anything. The first piece of information is redundant.

> The closure of all possible types ?
> like auto but if auto where not replaced ?

Your intuition is correct. In a higher-order type system, you can have:

(∀a. a) foo();

This says that foo returns a value that has any type you wish it to have.
Of course, there is no single value that has all types (ignoring e.g. 
full OO languages that have null references), hence we have no way to 
actually construct a value satisfying the constraints, so (∀a. a) is an 
empty type.

In languages with subtyping, Bottom is often just a subtype of all other 
types. (The name "Bottom" stems from here: 
https://en.wikipedia.org/wiki/Lattice_(order)#Bounded_lattice . The 
bounded lattice in question is the subtyping lattice, where A ≤ B means 
A is a subtype of B.)

One reason why it is nice to have a bounded subtyping lattice is that 
then, you can express subtyping constraints uniformly: A≤B does not 
constraint B if A is Bottom, and it does not constrain A if B is Top.





More information about the Digitalmars-d mailing list