July 18, 2017
On Monday, 17 July 2017 at 18:10:27 UTC, Andrei Alexandrescu wrote:
> On 7/17/17 11:39 AM, Olivier FAURE wrote:
>> I'd really prefer if you avoided the whole `typeof(assert(0))` thing.
>> 
>> First off, it's way too verbose for a simple concept.
>
> Noted, thanks. I won't debate this much but for now I disagree.

Fair enough.
July 18, 2017
On Monday, 17 July 2017 at 23:01:40 UTC, Walter Bright wrote:
> On 7/16/2017 5:41 AM, Timon Gehr wrote:
>> struct S{
>>     T x;
>>     Bottom everything;
>> }
>> 
>> turns the entire struct into an empty type. It is therefore most natural to say that Bottom.sizeof == ∞. (It's the only choice for which S.sizeof == Bottom.sizeof.)
>> 
>> Another way to think about it: If something of type A* converts to something of type B* without problems, then one would expect B.sizeof <= A.sizeof. This would imply that Bottom.sizeof >= size_t.max. (Because Bottom* converts to all other pointer types.)
>> 
>> One small issue is that one needs to avoid overflow for the size of a struct that has multiple fields where one of them is of type Bottom.
>> 
>
> But if Bottom does not exist, then S doesn't exist either, and hence the < size relationship has no meaning.
>
> (Reminds me of divide by 0 discussions in calculus class.)

Strictly speaking it just shouldn't have a sizeof, because sizeof is shorthand for "size of an instance of" (types don't really have sizes, how do I store the type "int" in memory?) and Bottom has no instances.

Infinity - or the next best applicable thing size_t.max - is a reasonable standin for an invalid value, except that people will do silly things like `auto paddedSpace =
 (ReturnType!foo).sizeof + 1;` and then you're in trouble.

Better to just not define it.

Is there some magic that can be done where all code that makes reference to an instance of Bottom just isn't compiled? I.e. if there happens to be a situation where a function returns Bottom then all code that touches that return type is just ignored?
July 18, 2017
On Tuesday, 18 July 2017 at 10:17:17 UTC, John Colvin wrote:

> how do I store the type "int" in memory?
new Type(TYENUM.Tint32); :o)

July 18, 2017
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.
July 18, 2017
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 ?
... and what does it actually represent ?
The closure of all possible types ?
like auto but if auto where not replaced ?
July 18, 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.



July 18, 2017
On Monday, 17 July 2017 at 18:54:37 UTC, H. S. Teoh wrote:
> On Mon, Jul 17, 2017 at 02:10:27PM -0400, Andrei Alexandrescu via Digitalmars-d wrote:
>> [...]
> [...]
>
> IMO, the observations "used rarely" and "attention-seeking notation" are better satisfied by an attribute named @noreturn than some strange, convoluted, arcane invocation like `typeof(assert(0))`.  Because:
>
> [...]

object.d:

alias noreturn = typeof(assert(0));

Atila
July 18, 2017
On Tuesday, 18 July 2017 at 15:26:59 UTC, Timon Gehr wrote:
> On 18.07.2017 14:19, Stefan Koch wrote:
>> [...]
>
> 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.)
>
> [...]

What about void?
July 18, 2017
On 18.07.2017 20:46, Yuxuan Shui wrote:
> On Tuesday, 18 July 2017 at 15:26:59 UTC, Timon Gehr wrote:
>> On 18.07.2017 14:19, Stefan Koch wrote:
>>> [...]
>>
>> 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.)
>>
>> [...]
> 
> What about void?

You can't have a value of type void, but it is not empty either.

For example, this means that the following transformation is not always valid:

return foo();

<->

auto x = foo();
return x;
July 18, 2017
On Tuesday, 18 July 2017 at 20:49:56 UTC, Timon Gehr wrote:
> On 18.07.2017 20:46, Yuxuan Shui wrote:
>> On Tuesday, 18 July 2017 at 15:26:59 UTC, Timon Gehr wrote:
>>> On 18.07.2017 14:19, Stefan Koch wrote:
>>>> [...]
>>>
>>> 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.)
>>>
>>> [...]
>> 
>> What about void?
>
> You can't have a value of type void, but it is not empty either.
>
> For example, this means that the following transformation is not always valid:
>
> return foo();

Could you explain why `return foo();` is even legal for a `void foo() {}`? I wasn't aware of it before and the fact that you can (syntactically) return the non-existent return value of `foo` raises cognitive dissonance flags for me. I imagine there's a type system reason?