proposed @noreturn attribute

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 13 10:25:18 PDT 2017


On Wednesday, 12 July 2017 at 14:23:15 UTC, Andrei Alexandrescu 
wrote:
> On 07/12/2017 05:32 AM, Timon Gehr wrote:
>> On 09.07.2017 23:45, Meta wrote:
>>> ...
>>> Another case that we should probably just statically disallow:
>>> ... > This obviously doesn't make any sense anyway
>>> ... > I don't see a reason for us to ever need to do that
>> Sorry, but this thinking has no place in type system design. 
>> This is precisely how you create a convoluted nonsensical mess.
>
> Timon, I think you're very well positioned to author a DIP on 
> this. Getting through acceptance on your static foreach DIP 
> seems to not require a lot of extra work.
> ...

I might do that, however there are a couple of open questions 
(see below).

>> Every type is peculiar. That's essentially the point of having
>> types. There is not really a reason to invent a peculiarity 
>> ordering
>> and then add additional special casing for types deemed more
>> peculiar. (I.e., creating different types of types based on an
>> informal judgment of peculiarity.)
> I seem to recall Haskell calls those "kinds".
> ...

Indeed, but the separation of types and kinds has no point.
See: https://ghc.haskell.org/trac/ghc/wiki/DependentHaskell

It's perfectly fine to have a type of types which is its own 
type, especially if you allow non-termination.

>> In D, subtyping is messy anyway, as you cannot have a subtyping
>> relationship between values with different memory layout. 
>> Hence in D,
>> Bottom would not actually be a subtype of all other types.
>
> It's a point, and it would make the implementation easier, but 
> it would be a departure from theory. Also it makes user code a 
> tad more awkward.

I'm saying the D notion of subtyping is a bit messy because 
memory layout matters and subtyping and implicit conversion are 
not the same thing. Anyway, my assertion that Bottom cannot be a 
subtype of all other types was actually incorrect: the compiler 
does not need to generate code for implicit conversion from 
Bottom to some other type, so it can be treated as a subtype.

(Also, a language does not have to support subtyping to have an 
empty type.)

typeof(assert(0))* and typeof(assert(0))[] will hence be subtypes 
of all other pointer and array types respectively.

An issue is that we already have typeof(null). typeof(null) and 
typeof(assert(0))* are two ways to specify almost the same thing. 
One question is whether typeof(assert(0))* and typeof(null) 
should be the same, or if the former should not implicitly 
convert to class references.
I have also argued in the past that there should be a separate 
typeof([]). This role would now be filled by typeof(assert(0))[]. 
However, changing the type of '[]' may break code.

> Consider:
>
> typeof(assert(0)) abort(const(char)[] message);
> ...
> int fun()
> {
>    int x;
>    ...
>    return x != 0 ? 1024 / x : abort("Error: calculation went 
> awry.");
> }
>
> I guess such expressions can be rewritten into separate 
> statements:
>
> if (x != 0) return 1024 / x;
> abort("Error: calculation went awry.");
>
> and then the compiler figures there's no need for a return 
> following the call to abort.
> ...

This code compiles and runs:

int x;
...
return x != 0 ? 1024 : (delegate int(){ assert(0,"Error: 
calculation went awry."); })();

> Perhaps a solid plan is to start with a DIP that does not 
> introduce conversion and then experiment with the result for a 
> while. What do you think?
> ...

I think the DIP should introduce conversion from the start, as 
conversion is easy to support. It is simple to support in the 
front end and the code gen for it is literally to emit nothing.




More information about the Digitalmars-d mailing list