Re: proposed @noreturn attribute

2017-07-24 Thread w0rp via Digitalmars-d
I didn't look through all of the replies to this thread to check 
that this hasn't been mentioned yet, but TypeScript uses the 
'never' return type for functions that never return.


https://www.typescriptlang.org/docs/handbook/basic-types.html#never

The type isn't used for any optimisations, it's only used for 
preventing you from adding lines of code after functions which 
never return. (Say if they run "forever" or throw exceptions.)


I thought it would be worth mentioning how another language 
handles this currently.


Re: proposed @noreturn attribute

2017-07-21 Thread Andrei Alexandrescu via Digitalmars-d

On 07/19/2017 10:32 AM, Timon Gehr wrote:

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for any other 
type.


AFAIK from type theory, bottom is defined as having no values (so one 
can't reason about the relationship of such non-existent value(s) to 
values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


Didn't know "false implies anything" comes with such a nice name. 
Thanks! -- Andrei


Re: proposed @noreturn attribute

2017-07-20 Thread Yuxuan Shui via Digitalmars-d

On Wednesday, 19 July 2017 at 10:35:37 UTC, Stefan Koch wrote:

On Wednesday, 19 July 2017 at 10:24:35 UTC, Marc Schütz wrote:
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some 
good consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said 
it can be "anything". A bottom type can not be anything, but 
only nothing.


It's the bottom.
Bottom is to Types, as Object is to Classes.


Actually, Object should be considered the Top type. All Classes 
are sub-classes of Object.


Re: proposed @noreturn attribute

2017-07-20 Thread Timon Gehr via Digitalmars-d

On 20.07.2017 00:21, Tobias Müller wrote:

Timon Gehr  wrote:

[...]
What I am saying is: in a language with a bottom type, we can create a
function:

T f(T)(Bottom b){
 return b; // assuming b converts to all types implicitly.
}

Within the function body, b is a value of type Bottom.
We use a value of type Bottom to create a value of any type we want.


As I understand it, you can create *variables* of type Bottom but not
*values*.


Correct.


b is a variable, not a value,


Within the function body, it is.


you cannot actually call that function at runtime.



Correct.


Re: proposed @noreturn attribute

2017-07-19 Thread Tobias Müller via Digitalmars-d
Timon Gehr  wrote:
> [...]
> What I am saying is: in a language with a bottom type, we can create a 
> function:
> 
> T f(T)(Bottom b){
> return b; // assuming b converts to all types implicitly.
> }
> 
> Within the function body, b is a value of type Bottom.
> We use a value of type Bottom to create a value of any type we want.

As I understand it, you can create *variables* of type Bottom but not
*values*.
b is a variable, not a value, you cannot actually call that function at
runtime.


Re: proposed @noreturn attribute

2017-07-19 Thread Walter Bright via Digitalmars-d

On 7/16/2017 6:03 AM, Timon Gehr wrote:
pragma(noreturn) is indeed the simpler solution, as it does not interact with 
anything else.
Pragmas are not supposed to change the semantics of the code, they are intended 
as directions to the compiler, such as:


* optimization suggestions
* embedding instructions into the object file
* sending messages to the user while compiling
* instructing the compiler on special name mangling

etc. A pragma(noreturn) influences semantics, and so is inappropriate. That's 
what attributes and types are for.


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 17:14, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 14:52:28 UTC, Timon Gehr wrote:

On 19.07.2017 16:47, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 14:32:24 UTC, Timon Gehr wrote:

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for any 
other type.


AFAIK from type theory, bottom is defined as having no values (so 
one can't reason about the relationship of such non-existent 
value(s) to values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


I am aware, but once a statement (and its negation) can be inferred 
from the same (false) proposition, one isn't reasoning anymore - and 
more importantly its not useful w.r.t. explaining what the bottom 
type is.


I disagree with both of those statements, but I'm not sure how any of 
this relates to the true sentence I wrote that you seemed to criticize.


The sentence I quoted states you can use a value of type bottom to 
construct a value of any other type; this means the existence of such a 
value of type bottom becomes an implicit premise.


Not really; see below.

As the bottom type is 
defined as having no values that premise does not hold, i.e. you can 
infer both
"a value of type bottom can be used to construct a value for any other 
type."

and
"a value of type bottom cannot be used to construct a value for any 
other type."
from it (principle of explosion, as you quoted). My original criticism 
was meant to convey that I do not consider the quoted sentence as being 
helpful w.r.t. explaining what the bottom type is (which the rest of the 
post I quoted the sentence from did quite well).


What I said does not /use/ the principle of explosion; it states it.

What I am saying is: in a language with a bottom type, we can create a 
function:


T f(T)(Bottom b){
return b; // assuming b converts to all types implicitly.
}

Within the function body, b is a value of type Bottom.
We use a value of type Bottom to create a value of any type we want.

The reason why I included that part of the sentence was: Not all 
programming languages have subtyping, but all programming languages with 
a bottom type allow a function of the above type to be constructed. 
(It's the induction principle for empty algebraic data types.)


For any T, the type of !T is T delegate(Bottom), or in different notation:
f: ∀a. ⊥ → a.

I.e., the type of f is the principle of explosion.


Re: proposed @noreturn attribute

2017-07-19 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 19 July 2017 at 14:52:28 UTC, Timon Gehr wrote:

On 19.07.2017 16:47, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 14:32:24 UTC, Timon Gehr wrote:

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for 
any other type.


AFAIK from type theory, bottom is defined as having no 
values (so one can't reason about the relationship of such 
non-existent value(s) to values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


I am aware, but once a statement (and its negation) can be 
inferred from the same (false) proposition, one isn't 
reasoning anymore - and more importantly its not useful w.r.t. 
explaining what the bottom type is.


I disagree with both of those statements, but I'm not sure how 
any of this relates to the true sentence I wrote that you 
seemed to criticize.


The sentence I quoted states you can use a value of type bottom 
to construct a value of any other type; this means the existence 
of such a value of type bottom becomes an implicit premise. As 
the bottom type is defined as having no values that premise does 
not hold, i.e. you can infer both
"a value of type bottom can be used to construct a value for any 
other type."

and
"a value of type bottom cannot be used to construct a value for 
any other type."
from it (principle of explosion, as you quoted). My original 
criticism was meant to convey that I do not consider the quoted 
sentence as being helpful w.r.t. explaining what the bottom type 
is (which the rest of the post I quoted the sentence from did 
quite well).


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 16:47, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 14:32:24 UTC, Timon Gehr wrote:

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for any 
other type.


AFAIK from type theory, bottom is defined as having no values (so one 
can't reason about the relationship of such non-existent value(s) to 
values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


I am aware, but once a statement (and its negation) can be inferred from 
the same (false) proposition, one isn't reasoning anymore - and more 
importantly its not useful w.r.t. explaining what the bottom type is.


I disagree with both of those statements, but I'm not sure how any of 
this relates to the true sentence I wrote that you seemed to criticize.


Re: proposed @noreturn attribute

2017-07-19 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 19 July 2017 at 14:32:24 UTC, Timon Gehr wrote:

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for 
any other type.


AFAIK from type theory, bottom is defined as having no values 
(so one can't reason about the relationship of such 
non-existent value(s) to values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


I am aware, but once a statement (and its negation) can be 
inferred from the same (false) proposition, one isn't reasoning 
anymore - and more importantly its not useful w.r.t. explaining 
what the bottom type is.


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 14:13, Moritz Maxeiner wrote:

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for any other 
type.


AFAIK from type theory, bottom is defined as having no values (so one 
can't reason about the relationship of such non-existent value(s) to 
values of other types).

https://en.wikipedia.org/wiki/Principle_of_explosion


Re: proposed @noreturn attribute

2017-07-19 Thread Marco Leise via Digitalmars-d
Am Wed, 19 Jul 2017 12:13:40 +
schrieb Moritz Maxeiner :

> On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
> > a value of type bottom can be used to construct a value for any 
> > other type.  
> 
> AFAIK from type theory, bottom is defined as having no values (so 
> one can't reason about the relationship of such non-existent 
> value(s) to values of other types).

2018, Dlang is now an esoteric language. After a long
bike-shedding the "bottom type" has been named "nirvana" and
assigning it to a variable of any other type signifies intent
to give the program a reincarnation. On Posix this was
efficiently implemented via fork and exec, Windows
implementation is still suffering from bad vibes (bugs).
Phobos comes in several flavors now, because it was discovered
that one Phobos can never be enough to capture all the worlds
paradigms and was considered the main offender to peace on the
forums. So there is now an assembly optimized fast Phobos for
performance fans without safety nor GC; a type theory Phobos
that tries hard to hide the fact that structs have a fixed data
layout and makes types first class citizens, but doesn't
interop with C at all; an auto-decoding Phobos; and a
batteries included Phobos with database drivers, audio, image
and GUI bindings.

-- 
Marco



Re: proposed @noreturn attribute

2017-07-19 Thread Meta via Digitalmars-d

On Wednesday, 19 July 2017 at 11:02:07 UTC, Marc Schütz wrote:

On Wednesday, 12 July 2017 at 13:22:46 UTC, Meta wrote:
D is not ML or Haskell or Idris. Rust has trod this ground 
before us and they saw it prudent to not make ! a first-class 
type.


Only to turn around after they realized their mistake:

https://doc.rust-lang.org/stable/book/second-edition/ch19-04-advanced-types.html#the-never-type--that-never-returns


That page doesn't say anything about passing ! as a type to 
generic functions (what I'm referring to), but it seems the 
following code does compile on Rust nightly with the 
#![feature(never_type)] directive:


fn test() {}

fn main() {
test::();
}

So it seems my Rust knowledge is about a year out of date.


Re: proposed @noreturn attribute

2017-07-19 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 19 July 2017 at 11:35:47 UTC, Timon Gehr wrote:
a value of type bottom can be used to construct a value for any 
other type.


AFAIK from type theory, bottom is defined as having no values (so 
one can't reason about the relationship of such non-existent 
value(s) to values of other types).


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 12:59, Stefan Koch wrote:

On Wednesday, 19 July 2017 at 10:44:22 UTC, Timon Gehr wrote:


No. Bottom is to types as typeof(null) is to class types.


I fear you lost me again :)

as far as I understood your previous explanation, every type is a 
subtype of bottom, is that incorrect ?


It is the other way around. Bottom is a subtype of every type / a value 
of type bottom can be used to construct a value for any other type.


Re: proposed @noreturn attribute

2017-07-19 Thread Marc Schütz via Digitalmars-d

On Wednesday, 12 July 2017 at 13:22:46 UTC, Meta wrote:
D is not ML or Haskell or Idris. Rust has trod this ground 
before us and they saw it prudent to not make ! a first-class 
type.


Only to turn around after they realized their mistake:

https://doc.rust-lang.org/stable/book/second-edition/ch19-04-advanced-types.html#the-never-type--that-never-returns


Re: proposed @noreturn attribute

2017-07-19 Thread Stefan Koch via Digitalmars-d

On Wednesday, 19 July 2017 at 10:44:22 UTC, Timon Gehr wrote:


No. Bottom is to types as typeof(null) is to class types.


I fear you lost me again :)

as far as I understood your previous explanation, every type is a 
subtype of bottom, is that incorrect ?


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 12:35, Stefan Koch wrote:

On Wednesday, 19 July 2017 at 10:24:35 UTC, Marc Schütz wrote:

On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some good 
consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said it can 
be "anything". A bottom type can not be anything, but only nothing.


It's the bottom.
Bottom is to Types, as Object is to Classes.



No. Bottom is to types as typeof(null) is to class types.


Re: proposed @noreturn attribute

2017-07-19 Thread Timon Gehr via Digitalmars-d

On 19.07.2017 12:24, Marc Schütz wrote:

On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some good 
consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said it can be 
"anything". A bottom type can not be anything, but only nothing.




There is nothing that can be anything, but anything can be top.

Natural language has an unfortunate tendency to blur the distinction 
between dual concepts as it gets more informal.


Re: proposed @noreturn attribute

2017-07-19 Thread Stefan Koch via Digitalmars-d

On Wednesday, 19 July 2017 at 10:24:35 UTC, Marc Schütz wrote:
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some good 
consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said 
it can be "anything". A bottom type can not be anything, but 
only nothing.


It's the bottom.
Bottom is to Types, as Object is to Classes.



Re: proposed @noreturn attribute

2017-07-19 Thread Marc Schütz via Digitalmars-d
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some good 
consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said it 
can be "anything". A bottom type can not be anything, but only 
nothing.




Re: proposed @noreturn attribute

2017-07-18 Thread Walter Bright via Digitalmars-d

On 7/18/2017 7:14 PM, Nicholas Wilson wrote:
It describe the behaviour of the function: I think it is neither necessary nor a 
good idea to express it as a type. assert(0) is already accepted as a valid 
return statement of any type.


I can't continue this without being repetitive, so we'll just have to disagree.


The backends for DMD, LDC and GDC would not be affected at all by the addition 
of a bottom type to the front end, and it would be trivial for the glue code 
to add the noreturn attribute for functions that return the bottom type.


Said glue would be unnecessary with an attribute *that already exists*.


In the glue code, replace:

if (function attribute is 'noreturn')
set backend attribute to 'noreturn';

with:

if (function return type is 'bottom')
set backend attribute to 'noreturn';
set backend function return type to 'void';

and it should be ready to rock :-)


Re: proposed @noreturn attribute

2017-07-18 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 19 July 2017 at 01:52:30 UTC, Walter Bright wrote:
I know how noreturn attributes work - I implemented them 
decades ago in DMC and DMC++. They are supported by the DMD 
optimizer and back end.


But they are a hack to the type system, and I suggest an 
unnecessary one.


It describe the behaviour of the function: I think it is neither 
necessary nor a good idea to express it as a type. assert(0) is 
already accepted as a valid return statement of any type.


The backends for DMD, LDC and GDC would not be affected at all 
by the addition of a bottom type to the front end, and it would 
be trivial for the glue code to add the noreturn attribute for 
functions that return the bottom type.


Said glue would be unnecessary with an attribute *that already 
exists*.


Re: proposed @noreturn attribute

2017-07-18 Thread Walter Bright via Digitalmars-d

On 7/18/2017 5:54 PM, Nicholas Wilson wrote:

There is just something fundamentally wrong with:
@noreturn int foo();
I would understand it to mean that if it were to return, foo would return an int 
but it is undefined behaviour for foo to dynamically return.


That's the C++ behavior. I know we are all accustomed to it and hence think it 
is intuitive, but it isn't. I know I've had a hard time breaking free of this 
sort of thinking, having been so deeply immersed in C++ for so long.



returning a value yet not returning. It smacks of "the language designer(s) 
are idiots." It winds up complicating things like:


auto x = a ? b : foo();

What is the type of x? @noreturn means a special case. A proper bottom type 
means it is not a special case.


int.


And if b is of type `T`? It doesn't make sense to have to give a type to 
something that does not return. (@noreturn functions are usually typed as 
returning `void` anyway, but that still doesn't make much sense.)


I know how noreturn attributes work - I implemented them decades ago in DMC and 
DMC++. They are supported by the DMD optimizer and back end.


But they are a hack to the type system, and I suggest an unnecessary one.

The backends for DMD, LDC and GDC would not be affected at all by the addition 
of a bottom type to the front end, and it would be trivial for the glue code to 
add the noreturn attribute for functions that return the bottom type.


Re: proposed @noreturn attribute

2017-07-18 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 18 July 2017 at 22:03:27 UTC, Walter Bright wrote:
The issue here (for me) is to have a type system that matches 
type systems used in type theory. D already has strong 
abilities to do type calculus. Instead of inventing our own 
whackadoodle scheme, one hack at a time, why not match existing 
type calculus? Then, attempts to do type calculus in D will 
work as worked out by type theory.


Or, we could go with the C++ approach which historically is to 
add an ad-hoc solution for an existing problem, and then 
another ad-hoc solution for the whacky effects that turned out 
to have, rinse, repeat. (Look at all the different ways to do 
type deduction, a horrifying consequence. Or function 
overloading, which started with complex special cases, then 
changed to partial ordering for special cases.)


There is just something fundamentally wrong with:

@noreturn int foo();


I would understand it to mean that if it were to return, foo 
would return an int but it is undefined behaviour for foo to 
dynamically return.


returning a value yet not returning. It smacks of "the language 
designer(s) are idiots." It winds up complicating things like:


auto x = a ? b : foo();

What is the type of x? @noreturn means a special case. A proper 
bottom type means it is not a special case.


int. @noreturn need not pollute the type, given the use cases for 
@noreturn. Namely to document that the function does not 
dynamically return and aid the compiler in optimisation (are 
there any other uses?). `assert(0);` is already accepted in the 
front end as an acceptable return "value" for any type e.g. in


Bar foo(int x)
{
foreach (e; data[])
 if (e.x == x)
  return e;
assert(0);
}

The language semantics and compiler internals should be simpler 
and cleaner by using accepted type theory.


Not for LDC or GDC. They already have the ability to signal to 
their backends that a function does not dynamically return.


as I have posted before, one can do (in core.attribute),

enum __noreturn;

version(LDC)
{
import ldc.attributes : llvmAttr;
alias noreturn = AliasSeq!(llvmAttr("noreturn"),__noreturn);
}
else version(GNU)
{
import gcc.attribute : llvmAttr;
alias noreturn = AliasSeq!(attribute("noreturn"),__noreturn);
}
else // DMD
{
alias noreturn = __noreturn;
}

for a complete implementation for LDC and GDC, and DMD can do 
whatever it needs to with the presence of __noreturn, including 
fronted semantic analysis.




Re: proposed @noreturn attribute

2017-07-18 Thread via Digitalmars-d

On Tuesday, 18 July 2017 at 22:03:27 UTC, Walter Bright wrote:

On 7/17/2017 4:26 PM, H. S. Teoh via Digitalmars-d wrote:

But the point is that so much time and effort is being spent on
discussing and designing a feature that you have admitted 
yourself to be
"rarely used". As a disinterested bystander I find it somewhat 
amusing
(and sad) to see so much over-engineering of an overly-complex 
system
involving a new basic type in the language, which in turn 
entails all
sorts of corner cases in how it will interact with existing 
types and
constructs, not to mention the implementation complexities 
that will be
involved to pull it off -- all for what?  Just to be able to 
say
"function F doesn't return".  Seems like disproportionate 
effort for

only marginal returns (har har).


The issue here (for me) is to have a type system that matches 
type systems used in type theory. D already has strong 
abilities to do type calculus. Instead of inventing our own 
whackadoodle scheme, one hack at a time, why not match existing 
type calculus? Then, attempts to do type calculus in D will 
work as worked out by type theory.


Or, we could go with the C++ approach which historically is to 
add an ad-hoc solution for an existing problem, and then 
another ad-hoc solution for the whacky effects that turned out 
to have, rinse, repeat. (Look at all the different ways to do 
type deduction, a horrifying consequence. Or function 
overloading, which started with complex special cases, then 
changed to partial ordering for special cases.)



[...]


Agreed. Discovered vs invented as Philip Wadler classifies the 
two approaches in his talk: 
https://www.youtube.com/watch?v=IOiZatlZtGU, which I highly 
recommend watching.


Re: proposed @noreturn attribute

2017-07-18 Thread Timon Gehr via Digitalmars-d

On 18.07.2017 23:35, Moritz Maxeiner wrote:


Could you explain why `return foo();` is even legal for a `void foo() 
{}`?


Because the ad-hoc decision to make void a type that is not really a 
type leads to unnecessary friction, and this exceptional rule removes 
the friction in one common special case.


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?


There should be. foo's return type could be a unit type, with just one 
value. Then foo does have a return value, but it is always the same and 
so does not need to be explicitly tracked.


Re: proposed @noreturn attribute

2017-07-18 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 18 July 2017 at 21:45:27 UTC, Adam D. Ruppe wrote:

On Tuesday, 18 July 2017 at 21:35:21 UTC, Moritz Maxeiner wrote:
Could you explain why `return foo();` is even legal for a 
`void foo() {}`?


Suppose you are writing a template function that forwards:

auto forward(alias fun, T...)(T args) {
   return fun(args);
}


It just saves you from having to static if(fun returns void).


That's a good pragmatic (syntactic sugar) reason, thanks.


Re: proposed @noreturn attribute

2017-07-18 Thread Walter Bright via Digitalmars-d

On 7/17/2017 4:26 PM, H. S. Teoh via Digitalmars-d wrote:

But the point is that so much time and effort is being spent on
discussing and designing a feature that you have admitted yourself to be
"rarely used". As a disinterested bystander I find it somewhat amusing
(and sad) to see so much over-engineering of an overly-complex system
involving a new basic type in the language, which in turn entails all
sorts of corner cases in how it will interact with existing types and
constructs, not to mention the implementation complexities that will be
involved to pull it off -- all for what?  Just to be able to say
"function F doesn't return".  Seems like disproportionate effort for
only marginal returns (har har).


The issue here (for me) is to have a type system that matches type systems used 
in type theory. D already has strong abilities to do type calculus. Instead of 
inventing our own whackadoodle scheme, one hack at a time, why not match 
existing type calculus? Then, attempts to do type calculus in D will work as 
worked out by type theory.


Or, we could go with the C++ approach which historically is to add an ad-hoc 
solution for an existing problem, and then another ad-hoc solution for the 
whacky effects that turned out to have, rinse, repeat. (Look at all the 
different ways to do type deduction, a horrifying consequence. Or function 
overloading, which started with complex special cases, then changed to partial 
ordering for special cases.)


There is just something fundamentally wrong with:

@noreturn int foo();

returning a value yet not returning. It smacks of "the language designer(s) are 
idiots." It winds up complicating things like:


auto x = a ? b : foo();

What is the type of x? @noreturn means a special case. A proper bottom type 
means it is not a special case.



I recall that Rust initially did @noreturn as a special case, and later replaced 
that with a bottom type and integrated it into the type system. I understand 
that this had a positive ripple effect, such as reducing special cases in user 
generic code.


Noreturn functions are just a happy fallout of doing this correctly in the first 
place. The language semantics and compiler internals should be simpler and 
cleaner by using accepted type theory.


Re: proposed @noreturn attribute

2017-07-18 Thread Adam D. Ruppe via Digitalmars-d

On Tuesday, 18 July 2017 at 21:35:21 UTC, Moritz Maxeiner wrote:
Could you explain why `return foo();` is even legal for a `void 
foo() {}`?


Suppose you are writing a template function that forwards:

auto forward(alias fun, T...)(T args) {
   return fun(args);
}


It just saves you from having to static if(fun returns void).


Re: proposed @noreturn attribute

2017-07-18 Thread Moritz Maxeiner via Digitalmars-d

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?




Re: proposed @noreturn attribute

2017-07-18 Thread Timon Gehr via Digitalmars-d

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;


Re: proposed @noreturn attribute

2017-07-18 Thread Yuxuan Shui via Digitalmars-d

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?


Re: proposed @noreturn attribute

2017-07-18 Thread Atila Neves via Digitalmars-d

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


Re: proposed @noreturn attribute

2017-07-18 Thread Timon Gehr via Digitalmars-d

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.






Re: proposed @noreturn attribute

2017-07-18 Thread Stefan Koch via Digitalmars-d

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 ?


Re: proposed @noreturn attribute

2017-07-18 Thread Timon Gehr via Digitalmars-d

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.


Re: proposed @noreturn attribute

2017-07-18 Thread Stefan Koch via Digitalmars-d

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)



Re: proposed @noreturn attribute

2017-07-18 Thread John Colvin via Digitalmars-d

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?


Re: proposed @noreturn attribute

2017-07-18 Thread Olivier FAURE via Digitalmars-d
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.


Re: proposed @noreturn attribute

2017-07-17 Thread Timon Gehr via Digitalmars-d

On 18.07.2017 03:06, Walter Bright wrote:

On 7/17/2017 5:13 PM, Timon Gehr wrote:

(Reminds me of divide by 0 discussions in calculus class.)


The reason division by 0 is left undefined is that instead saying 1/0 
= ∞ introduces a new number ∞ that does not play nice with the axioms 
of a complete ordered field.


The question for instance size is based on the wrong assumption that 
there is such an instance. It is true none the less that ∞ is the most 
natural answer to this question, as if you have multiple answers for 
instance size, you'd take the supremum. Of course, size_t does not 
contain ∞.


Infinity makes sense for 1/0, but I don't see how that automatically 
transfers to size_t.


It does not. The reasoning is unrelated.


Re: proposed @noreturn attribute

2017-07-17 Thread Walter Bright via Digitalmars-d

On 7/17/2017 5:13 PM, Timon Gehr wrote:

(Reminds me of divide by 0 discussions in calculus class.)


The reason division by 0 is left undefined is that instead saying 1/0 = ∞ 
introduces a new number ∞ that does not play nice with the axioms of a complete 
ordered field.


The question for instance size is based on the wrong assumption that there is 
such an instance. It is true none the less that ∞ is the most natural answer to 
this question, as if you have multiple answers for instance size, you'd take the 
supremum. Of course, size_t does not contain ∞.


Infinity makes sense for 1/0, but I don't see how that automatically transfers 
to size_t.


Re: proposed @noreturn attribute

2017-07-17 Thread Nicholas Wilson via Digitalmars-d

On Monday, 17 July 2017 at 18:54:37 UTC, H. S. Teoh 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:


(1) "used rarely" means it should be as non-intrusive as 
possible as far as the language is concerned -- we should not 
spend a lot of language real estate on something that's rarely 
used, nor should it be something complicated to implement, 
and/or introduces tricky corner cases that we're likely to get 
wrong on first attempt. A @noreturn attribute is non-intrusive 
-- doesn't interact with anything else in the language, easy to 
implement -- has no tricky corner cases.


(2) "attention-seeking": an arcane invocation like 
`typeof(assert(0))` is harder to parse and therefore more 
likely to invite people to just gloss over it as 
"incomprehensible gibberish that I'll just ignore unless I have 
to look further", than catch people's attention.  Whereas an 
annotation like `@noreturn` is immediately obvious by its very 
presence, with a name that instantly tells you what it does 
while it still holds your attention.


I see `typeof(assert(0))` as the same kind of over-engineering 
of
something trivially solved and relatively unimportant ("rarely 
used")
that has unfortunately plagued C++ design and led C++ to become 
the mess

it is today.  It's sad to see D start down the same path...


T


(3) LDC and GDC already have an implementation in the form of an 
attribute so we can just have an AliasSeq of the front end 
recognised attribute and the one for GDC and LDC (assuming my 
attributes DIP goes through).




Re: proposed @noreturn attribute

2017-07-17 Thread Brad Roberts via Digitalmars-d

On 7/17/2017 5:06 PM, Seb via Digitalmars-d wrote:


I can't agree more. This is textbook procrastination and bike-shedding [1]!
There are dozens of open regressions that could have fixed or great, 
stalled PRs that could have been reviewed.
In fact if only PRs would be as heartily reviewed as the discussion 
here, things like the fact that DMD leaks all symbols when imported 
selectively [2] would have been uncovered earlier.


[1] https://en.wikipedia.org/wiki/Law_of_triviality
[2] https://github.com/dlang/phobos/pull/5584#issuecomment-314910297


Semi-valid, but fungability of time and effort>.


Re: proposed @noreturn attribute

2017-07-17 Thread Timon Gehr via Digitalmars-d

On 18.07.2017 01:01, Walter Bright wrote:

...

But if Bottom does not exist, then S doesn't exist either, and hence the 
< size relationship has no meaning.

...


Both Bottom and S exist, but they have no instances.


(Reminds me of divide by 0 discussions in calculus class.)


The reason division by 0 is left undefined is that instead saying 1/0 = 
∞ introduces a new number ∞ that does not play nice with the axioms of a 
complete ordered field.


The question for instance size is based on the wrong assumption that 
there is such an instance. It is true none the less that ∞ is the most 
natural answer to this question, as if you have multiple answers for 
instance size, you'd take the supremum. Of course, size_t does not 
contain ∞.


Re: proposed @noreturn attribute

2017-07-17 Thread Seb via Digitalmars-d

On Monday, 17 July 2017 at 23:26:18 UTC, H. S. Teoh wrote:


Actually, I don't really care enough about this issue to want 
it to be implemented one way or another, as long as there is 
*some* way to annotate a non-returning function.


But the point is that so much time and effort is being spent on 
discussing and designing a feature that you have admitted 
yourself to be "rarely used". As a disinterested bystander I 
find it somewhat amusing (and sad) to see so much 
over-engineering of an overly-complex system involving a new 
basic type in the language, which in turn entails all sorts of 
corner cases in how it will interact with existing types and 
constructs, not to mention the implementation complexities that 
will be involved to pull it off -- all for what?  Just to be 
able to say "function F doesn't return".  Seems like 
disproportionate effort for only marginal returns (har har).



I can't agree more. This is textbook procrastination and 
bike-shedding [1]!
There are dozens of open regressions that could have fixed or 
great, stalled PRs that could have been reviewed.
In fact if only PRs would be as heartily reviewed as the 
discussion here, things like the fact that DMD leaks all symbols 
when imported selectively [2] would have been uncovered earlier.


[1] https://en.wikipedia.org/wiki/Law_of_triviality
[2] 
https://github.com/dlang/phobos/pull/5584#issuecomment-314910297


Re: proposed @noreturn attribute

2017-07-17 Thread H. S. Teoh via Digitalmars-d
On Mon, Jul 17, 2017 at 06:42:02PM -0400, Andrei Alexandrescu via Digitalmars-d 
wrote:
> On 7/17/17 2:54 PM, H. S. Teoh via Digitalmars-d wrote:
> > I see `typeof(assert(0))` as the same kind of over-engineering of
> > something trivially solved and relatively unimportant ("rarely
> > used") that has unfortunately plagued C++ design and led C++ to
> > become the mess it is today.  It's sad to see D start down the same
> > path...
> 
> There is no reason to over-react seeing as the option of adding a name
> is easy and always available; removing it not so much. This makes
> taking options in language design highly asymmetrical. Having the type
> available as an actual expression brings good options on the table
> because people can return those on unreachable paths etc. -- Andrei

Actually, I don't really care enough about this issue to want it to be
implemented one way or another, as long as there is *some* way to
annotate a non-returning function.

But the point is that so much time and effort is being spent on
discussing and designing a feature that you have admitted yourself to be
"rarely used". As a disinterested bystander I find it somewhat amusing
(and sad) to see so much over-engineering of an overly-complex system
involving a new basic type in the language, which in turn entails all
sorts of corner cases in how it will interact with existing types and
constructs, not to mention the implementation complexities that will be
involved to pull it off -- all for what?  Just to be able to say
"function F doesn't return".  Seems like disproportionate effort for
only marginal returns (har har).


T

-- 
Those who don't understand D are condemned to reinvent it, poorly. -- Daniel N


Re: proposed @noreturn attribute

2017-07-17 Thread Walter Bright via Digitalmars-d

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.)


Re: proposed @noreturn attribute

2017-07-17 Thread Walter Bright via Digitalmars-d

On 7/16/2017 1:15 PM, Timon Gehr wrote:

In this case, Bottom.sizeof is a value of type Bottom, which must not exist.


T.sizeof is a value of type size_t, not type T.


Re: proposed @noreturn attribute

2017-07-17 Thread Andrei Alexandrescu via Digitalmars-d

On 7/17/17 2:54 PM, H. S. Teoh via Digitalmars-d wrote:

I see `typeof(assert(0))` as the same kind of over-engineering of
something trivially solved and relatively unimportant ("rarely used")
that has unfortunately plagued C++ design and led C++ to become the mess
it is today.  It's sad to see D start down the same path...


There is no reason to over-react seeing as the option of adding a name 
is easy and always available; removing it not so much. This makes taking 
options in language design highly asymmetrical. Having the type 
available as an actual expression brings good options on the table 
because people can return those on unreachable paths etc. -- Andrei


Re: proposed @noreturn attribute

2017-07-17 Thread Stefan Koch via Digitalmars-d

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:

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. The "no return" type has several particular 
properties that set it aside (e.g. it's impossible to 
implement as a library, does things no other types do, etc).  
It's also used rarely. Therefore it stands to reason to 
consider an attention-seeking notation for it.

[...]

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:


(1) "used rarely" means it should be as non-intrusive as 
possible as far as the language is concerned -- we should not 
spend a lot of language real estate on something that's rarely 
used, nor should it be something complicated to implement, 
and/or introduces tricky corner cases that we're likely to get 
wrong on first attempt. A @noreturn attribute is non-intrusive 
-- doesn't interact with anything else in the language, easy to 
implement -- has no tricky corner cases.


(2) "attention-seeking": an arcane invocation like 
`typeof(assert(0))` is harder to parse and therefore more 
likely to invite people to just gloss over it as 
"incomprehensible gibberish that I'll just ignore unless I have 
to look further", than catch people's attention.  Whereas an 
annotation like `@noreturn` is immediately obvious by its very 
presence, with a name that instantly tells you what it does 
while it still holds your attention.


I see `typeof(assert(0))` as the same kind of over-engineering 
of
something trivially solved and relatively unimportant ("rarely 
used")
that has unfortunately plagued C++ design and led C++ to become 
the mess

it is today.  It's sad to see D start down the same path...


T


+1000!
You've said it all!


Re: proposed @noreturn attribute

2017-07-17 Thread H. S. Teoh via Digitalmars-d
On Mon, Jul 17, 2017 at 02:10:27PM -0400, Andrei Alexandrescu via Digitalmars-d 
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. The
> "no return" type has several particular properties that set it aside
> (e.g. it's impossible to implement as a library, does things no other
> types do, etc).  It's also used rarely. Therefore it stands to reason
> to consider an attention-seeking notation for it.
[...]

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:

(1) "used rarely" means it should be as non-intrusive as possible as far
as the language is concerned -- we should not spend a lot of language
real estate on something that's rarely used, nor should it be something
complicated to implement, and/or introduces tricky corner cases that
we're likely to get wrong on first attempt. A @noreturn attribute is
non-intrusive -- doesn't interact with anything else in the language,
easy to implement -- has no tricky corner cases.

(2) "attention-seeking": an arcane invocation like `typeof(assert(0))`
is harder to parse and therefore more likely to invite people to just
gloss over it as "incomprehensible gibberish that I'll just ignore
unless I have to look further", than catch people's attention.  Whereas
an annotation like `@noreturn` is immediately obvious by its very
presence, with a name that instantly tells you what it does while it
still holds your attention.

I see `typeof(assert(0))` as the same kind of over-engineering of
something trivially solved and relatively unimportant ("rarely used")
that has unfortunately plagued C++ design and led C++ to become the mess
it is today.  It's sad to see D start down the same path...


T

-- 
I see that you JS got Bach.


Re: proposed @noreturn attribute

2017-07-17 Thread Andrei Alexandrescu via Digitalmars-d

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. The "no 
return" type has several particular properties that set it aside (e.g. 
it's impossible to implement as a library, does things no other types 
do, etc). It's also used rarely. Therefore it stands to reason to 
consider an attention-seeking notation for it.


The upside of this is we can always add an alias to give the type a name 
if we so wish. For now I'd want to experiment with using typeof as notation.



Andrei


Re: proposed @noreturn attribute

2017-07-17 Thread Patrick Schluter via Digitalmars-d

On Monday, 17 July 2017 at 15:39:30 UTC, Olivier FAURE wrote:
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
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.


You're on to something here. Perhaps we go the inverse route 
and define the bottom type as typeof(*null). Would that 
simplify matters? There is some good consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.

The latter is a mere consequence of the former.


I'd really prefer if you avoided the whole `typeof(assert(0))` 
thing.


First off, it's way too verbose for a simple concept. In 
general, code is much more readable when you can read functions 
as `Type functionName(args)`, rather than template-style 
`expr(valueof!(thing + otherThing).typeof) functionName(args)`, 
so I think it would be better not to encourage adding more 
expressions as return types.


I think the following:

noreturn_t logThenQuit(string message)

is much more readable and obvious (especially to a beginner) 
than:


typeof(*null) logThenQuit(string message)

Of course, you could implement typeof(*null); and also add 
noreturn_t as an alias; it might be a good compromise; I'd 
still dislike it because it encourages people to use the 
verbose hard to understand version.


The second reason I don't like it is that I feel it's just 
trying to be clever for the sake of cleverness. I don't think 
we need a language feature that perfectly matches the idea of 
not returning from a function on a deep, philosophical level; 
we just need a way to tell the type system "Hey, this function 
doesn't return!".


I don't think `typeof(*null)`, or `typeof(assert(0))` brings 
any advantage in term of real life user code, and I don't think 
it's worth the confused users that would look at code and go 
"Uh? What is the type of *null?" or "I thought assert was void! 
What would you get the type of assert()?".


Yes, this!



Re: proposed @noreturn attribute

2017-07-17 Thread Olivier FAURE via Digitalmars-d
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
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.


You're on to something here. Perhaps we go the inverse route 
and define the bottom type as typeof(*null). Would that 
simplify matters? There is some good consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.

The latter is a mere consequence of the former.


I'd really prefer if you avoided the whole `typeof(assert(0))` 
thing.


First off, it's way too verbose for a simple concept. In general, 
code is much more readable when you can read functions as `Type 
functionName(args)`, rather than template-style 
`expr(valueof!(thing + otherThing).typeof) functionName(args)`, 
so I think it would be better not to encourage adding more 
expressions as return types.


I think the following:

noreturn_t logThenQuit(string message)

is much more readable and obvious (especially to a beginner) than:

typeof(*null) logThenQuit(string message)

Of course, you could implement typeof(*null); and also add 
noreturn_t as an alias; it might be a good compromise; I'd still 
dislike it because it encourages people to use the verbose hard 
to understand version.


The second reason I don't like it is that I feel it's just trying 
to be clever for the sake of cleverness. I don't think we need a 
language feature that perfectly matches the idea of not returning 
from a function on a deep, philosophical level; we just need a 
way to tell the type system "Hey, this function doesn't return!".


I don't think `typeof(*null)`, or `typeof(assert(0))` brings any 
advantage in term of real life user code, and I don't think it's 
worth the confused users that would look at code and go "Uh? What 
is the type of *null?" or "I thought assert was void! What would 
you get the type of assert()?".


Re: proposed @noreturn attribute

2017-07-16 Thread Guillaume Boucher via Digitalmars-d

On Sunday, 16 July 2017 at 20:15:11 UTC, Timon Gehr wrote:

On 16.07.2017 21:49, Guillaume Boucher wrote:

On Sunday, 16 July 2017 at 12:41:06 UTC, Timon Gehr wrote:

It is therefore most natural to say that Bottom.sizeof == ∞.


True, but size_t.max doesn't have the properties of ∞.
The only sane choice to me seems to be a value of type Bottom, 
i.e. is(typeof(Bottom.sizeof) == Bottom).




In this case, Bottom.sizeof is a value of type Bottom, which 
must not exist.


It doesn't exist during runtime, but there's no problem to just 
generate assert(0) where it's used.


I think my interpretation produces the least exceptions, but if 
you have a better idea go ahead.




Re: proposed @noreturn attribute

2017-07-16 Thread Guillaume Boucher via Digitalmars-d

On Sunday, 16 July 2017 at 20:04:25 UTC, Timon Gehr wrote:
The issue isn't purism, it is type safety. If you create an 
EvolvedPenguin, upcast it to a Penguin and call the fly method 
you get UB. So noreturn would indeed need to enforce that all 
overrides are also noreturn.


I see it as some kind of weak guarantee, where the compiler can 
assume noreturn only if he knows there are no subtypes involved 
(e.g. if he's applying devirtualization).


Automatically inheriting the attribute could break existing code 
(especially if it's inferred).


Re: proposed @noreturn attribute

2017-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 07/13/2017 01:25 PM, Timon Gehr wrote:

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).


Sorry missed those... let's see:

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




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.




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


Wow. Cool!

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.


You're on to something here. Perhaps we go the inverse route and define 
the bottom type as typeof(*null). Would that simplify matters? There is 
some good consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.

The latter is a mere consequence of the former.

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.


Fantastic. Please kick it off. Thanks!!


Andrei


Re: proposed @noreturn attribute

2017-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 07/16/2017 04:15 PM, Timon Gehr wrote:

On 16.07.2017 21:49, Guillaume Boucher wrote:

On Sunday, 16 July 2017 at 12:41:06 UTC, Timon Gehr wrote:

It is therefore most natural to say that Bottom.sizeof == ∞.


True, but size_t.max doesn't have the properties of ∞.
The only sane choice to me seems to be a value of type Bottom, i.e. 
is(typeof(Bottom.sizeof) == Bottom).




In this case, Bottom.sizeof is a value of type Bottom, which must not 
exist.


Yah that's not workable. Generally the fewer odd exceptions the better, 
lest all generic code going forward will have to account for those.


Timon, since you got your first DIP approved, now is the time to keep 
the momentum going with a new one!



Andrei


Re: proposed @noreturn attribute

2017-07-16 Thread Timon Gehr via Digitalmars-d

On 16.07.2017 21:49, Guillaume Boucher wrote:

On Sunday, 16 July 2017 at 12:41:06 UTC, Timon Gehr wrote:

It is therefore most natural to say that Bottom.sizeof == ∞.


True, but size_t.max doesn't have the properties of ∞.
The only sane choice to me seems to be a value of type Bottom, i.e. 
is(typeof(Bottom.sizeof) == Bottom).




In this case, Bottom.sizeof is a value of type Bottom, which must not exist.


Re: proposed @noreturn attribute

2017-07-16 Thread Timon Gehr via Digitalmars-d

On 16.07.2017 21:49, Guillaume Boucher wrote:


I'd say a function with return type Bottom can override any function 
in the base class.


That solves the "Penguin : Bird" step, but not "EvolvedPenguin : 
Penguin" (which can fly).


Andrei argues that my example don't comply with a puristic understanding 
of inheritance.  Maybe that's enough of a reason to not optimize such 
use cases, but it still shows that pragma(noreturn) is somehow stronger 
than Bottom.


The issue isn't purism, it is type safety. If you create an 
EvolvedPenguin, upcast it to a Penguin and call the fly method you get 
UB. So noreturn would indeed need to enforce that all overrides are also 
noreturn.


Re: proposed @noreturn attribute

2017-07-16 Thread Guillaume Boucher via Digitalmars-d

On Sunday, 16 July 2017 at 12:41:06 UTC, Timon Gehr wrote:

It is therefore most natural to say that Bottom.sizeof == ∞.


True, but size_t.max doesn't have the properties of ∞.
The only sane choice to me seems to be a value of type Bottom, 
i.e. is(typeof(Bottom.sizeof) == Bottom).




Re: proposed @noreturn attribute

2017-07-16 Thread Guillaume Boucher via Digitalmars-d

On Sunday, 16 July 2017 at 13:03:40 UTC, Timon Gehr wrote:
I don't think that's true.  A Bottom type does not cover all 
use cases of @noreturn/@pragma(noreturn).

...


I think it does, but it is a significantly more invasive 
language change.


The best you can hope for is that any code with pragma(noreturn) 
can be rewritten into functionally equivalent code that uses 
Bottom and gives the same hints to the optimizer.


pragma(noreturn) can be inferred implicitly which makes it more 
impactful in practice.


I'd say a function with return type Bottom can override any 
function in the base class.


That solves the "Penguin : Bird" step, but not "EvolvedPenguin : 
Penguin" (which can fly).


Andrei argues that my example don't comply with a puristic 
understanding of inheritance.  Maybe that's enough of a reason to 
not optimize such use cases, but it still shows that 
pragma(noreturn) is somehow stronger than Bottom.



pragma(noreturn) is indeed the simpler solution, as it does not 
interact with anything else. The fact that template constraints 
in some cases need to be aware of the existence of Bottom in 
order to work for Bottom is clearly a negative property of this 
solution in the context of D.


Yes, basically this.


You can return 'auto' instead of U. Then the return type will 
be inferred either as U or Bottom.


Sure there are workarounds.  Also here:

auto deref(T)(ref T* x) { return deref(*x); }
ref T deref(T)(ref T x) if (!isPointer!T) { return x; }

But when every small function needs a rewrite, something seems 
off.


Re: proposed @noreturn attribute

2017-07-16 Thread Timon Gehr via Digitalmars-d

On 14.07.2017 17:39, Guillaume Boucher wrote:

On Monday, 10 July 2017 at 04:02:59 UTC, Nicholas Wilson wrote:

1)@noreturn
2)@disable(return)
3)none

w.r.t optimisation assuming both 1 & 3  impact DMD equally [...]


I don't think that's true.  A Bottom type does not cover all use cases 
of @noreturn/@pragma(noreturn).

...


I think it does, but it is a significantly more invasive language change.


Example 1: Polymorphism

class Bird { void fly() { ... } };
class Penguin : Bird { override void fly() @pragma(noreturn) { 
assert(0); }  };

class EvolvedPenguin : Penguin { override void fly() { ... } };

There's no way to encode that information in a return type.
...


I'd say a function with return type Bottom can override any function in 
the base class.



Example 2: Compile-time polymorphism

Same as above, except during compile time.  While it looks ok in theory 
(just return Bottom, and everything is alright), it seems very tricky to 
get right.  Example from checkedint.d:


auto r = hook.hookOpUnary!op(payload);
return Checked!(typeof(r), Hook)(r);

Let's say the hook refuses to perform hookOpUnary, so r is Bottom.  
Unfortunately, Checked!(Bottom, Hook)(r) doesn't compile (because "if 
(isIntegral!T || is(T == Checked!(U, H), U, H))" fails).  While Bottom 
may be substituted into all expressions (which doesn't seem easy 
anyway), it for sure can't be inserted as any template argument.  As 
seen before, Checked is not Bottom-proof.  I would think that most 
templates are not Bottom-proof and making them Bottom-proof seems quite 
a bit of work.

...


The problem for this example is that the current implementation of 
isIntegral would return false for Bottom.



With @pragma(noreturn) that situation would be no problem.
...


pragma(noreturn) is indeed the simpler solution, as it does not interact 
with anything else. The fact that template constraints in some cases 
need to be aware of the existence of Bottom in order to work for Bottom 
is clearly a negative property of this solution in the context of D.



Example 3: Unreachable statements/Implicit noreturn inference

As pointed out by Steven Schveighoffer, the current unreachability 
errors should probably be removed in generic code.


If we do that, then generic functions can be @pragma(noreturn) if 
certain conditions are met.  A compiler can easily figure that out, but 
writing it inside static ifs could be almost impossible.


Assume we have a hook to Checked that disallows casts.  Current signature:

U opCast(U, this _)() if (isIntegral!U || isFloatingPoint!U || is(U == 
bool))


The compiler can figure out that all code paths end with an 
@pragma(noreturn), so it can add that pragma implicitly to the 
signature.  However, the compiler can't change the return type from U to 
Bottom (otherwise static equality checks with U will fail).




You can return 'auto' instead of U. Then the return type will be 
inferred either as U or Bottom.




Re: proposed @noreturn attribute

2017-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 07/15/2017 11:30 PM, Walter Bright wrote:

On 7/13/2017 5:18 PM, Andrei Alexandrescu wrote:

On 7/13/17 2:37 PM, Timon Gehr wrote:

On Thursday, 13 July 2017 at 17:25:18 UTC, Timon Gehr wrote:
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.

...


(Actually, there are some complications like the .sizeof property. 
Anyway, it is clear what the semantics of Bottom are, no matter 
whether it is subtyping or implicit conversion.)


I wonder if sizeof could be made size_t.max. -- Andrei


I thought bottom.sizeof would be 0.


My thinking comes from bottom being the subtype of all types in the 
universe. Therefore, it must include the state of all types. But let's 
wait for Timon. -- Andrei


Re: proposed @noreturn attribute

2017-07-16 Thread Timon Gehr via Digitalmars-d

On 16.07.2017 05:30, Walter Bright wrote:

On 7/13/2017 5:18 PM, Andrei Alexandrescu wrote:

On 7/13/17 2:37 PM, Timon Gehr wrote:

On Thursday, 13 July 2017 at 17:25:18 UTC, Timon Gehr wrote:
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.

...


(Actually, there are some complications like the .sizeof property. 
Anyway, it is clear what the semantics of Bottom are, no matter 
whether it is subtyping or implicit conversion.)


I wonder if sizeof could be made size_t.max. -- Andrei


I thought bottom.sizeof would be 0.


0 is the obvious size for the unit type (the type with a single value, 
in D this is for example void[0]), as in:


struct S{
T x;
void[0] nothing;
}
static assert(S.sizeof == T.sizeof);

on the other hand

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.




Re: proposed @noreturn attribute

2017-07-15 Thread Walter Bright via Digitalmars-d

On 7/13/2017 5:18 PM, Andrei Alexandrescu wrote:

On 7/13/17 2:37 PM, Timon Gehr wrote:

On Thursday, 13 July 2017 at 17:25:18 UTC, Timon Gehr wrote:
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.

...


(Actually, there are some complications like the .sizeof property. Anyway, it 
is clear what the semantics of Bottom are, no matter whether it is subtyping 
or implicit conversion.)


I wonder if sizeof could be made size_t.max. -- Andrei


I thought bottom.sizeof would be 0.


Re: proposed @noreturn attribute

2017-07-14 Thread Andrei Alexandrescu via Digitalmars-d

On 07/14/2017 03:06 PM, Lurker wrote:

On Friday, 14 July 2017 at 15:39:01 UTC, Guillaume Boucher wrote:

Example 1: Polymorphism

class Bird { void fly() { ... } };
class Penguin : Bird { override void fly() @pragma(noreturn) { 
assert(0); }  };

class EvolvedPenguin : Penguin { override void fly() { ... } };



No matter how you look at it, this code should simply not be allowed:

Bird bird = ...;
bird.fly(); // is this return or noreturn?

Penguin penguin = ...;
penguin.fly(); // is this return or noreturn?

In both cases, compiler cannot draw any conclusions about 
return/noreturn and thus I believe such code should not be allowed.


Conventional thinking has it that derived methods should "require less 
and deliver more" such that substitution is possible. That's where 
contravariant parameters and covariant returns come from. Therefore, 
methods that do not return should be able to override those that return. 
(The opposite is unworkable btw.) Note that the absence of a "noreturn" 
annotation does not imply a guarantee that the method does return.


Andrei


Re: proposed @noreturn attribute

2017-07-14 Thread Lurker via Digitalmars-d

On Friday, 14 July 2017 at 15:39:01 UTC, Guillaume Boucher wrote:

Example 1: Polymorphism

class Bird { void fly() { ... } };
class Penguin : Bird { override void fly() @pragma(noreturn) { 
assert(0); }  };

class EvolvedPenguin : Penguin { override void fly() { ... } };



No matter how you look at it, this code should simply not be 
allowed:


Bird bird = ...;
bird.fly(); // is this return or noreturn?

Penguin penguin = ...;
penguin.fly(); // is this return or noreturn?

In both cases, compiler cannot draw any conclusions about 
return/noreturn and thus I believe such code should not be 
allowed.


And if this is disallowed, a Bottom type would fit again.


Re: proposed @noreturn attribute

2017-07-14 Thread Guillaume Boucher via Digitalmars-d

On Monday, 10 July 2017 at 04:02:59 UTC, Nicholas Wilson wrote:

1)@noreturn
2)@disable(return)
3)none

w.r.t optimisation assuming both 1 & 3  impact DMD equally [...]


I don't think that's true.  A Bottom type does not cover all use 
cases of @noreturn/@pragma(noreturn).


Example 1: Polymorphism

class Bird { void fly() { ... } };
class Penguin : Bird { override void fly() @pragma(noreturn) { 
assert(0); }  };

class EvolvedPenguin : Penguin { override void fly() { ... } };

There's no way to encode that information in a return type.

Example 2: Compile-time polymorphism

Same as above, except during compile time.  While it looks ok in 
theory (just return Bottom, and everything is alright), it seems 
very tricky to get right.  Example from checkedint.d:


auto r = hook.hookOpUnary!op(payload);
return Checked!(typeof(r), Hook)(r);

Let's say the hook refuses to perform hookOpUnary, so r is 
Bottom.  Unfortunately, Checked!(Bottom, Hook)(r) doesn't compile 
(because "if (isIntegral!T || is(T == Checked!(U, H), U, H))" 
fails).  While Bottom may be substituted into all expressions 
(which doesn't seem easy anyway), it for sure can't be inserted 
as any template argument.  As seen before, Checked is not 
Bottom-proof.  I would think that most templates are not 
Bottom-proof and making them Bottom-proof seems quite a bit of 
work.


With @pragma(noreturn) that situation would be no problem.

Example 3: Unreachable statements/Implicit noreturn inference

As pointed out by Steven Schveighoffer, the current 
unreachability errors should probably be removed in generic code.


If we do that, then generic functions can be @pragma(noreturn) if 
certain conditions are met.  A compiler can easily figure that 
out, but writing it inside static ifs could be almost impossible.


Assume we have a hook to Checked that disallows casts.  Current 
signature:


U opCast(U, this _)() if (isIntegral!U || isFloatingPoint!U || 
is(U == bool))


The compiler can figure out that all code paths end with an 
@pragma(noreturn), so it can add that pragma implicitly to the 
signature.  However, the compiler can't change the return type 
from U to Bottom (otherwise static equality checks with U will 
fail).




Re: proposed @noreturn attribute

2017-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/17 2:37 PM, Timon Gehr wrote:

On Thursday, 13 July 2017 at 17:25:18 UTC, Timon Gehr wrote:
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.

...


(Actually, there are some complications like the .sizeof property. 
Anyway, it is clear what the semantics of Bottom are, no matter whether 
it is subtyping or implicit conversion.)


I wonder if sizeof could be made size_t.max. -- Andrei


Re: proposed @noreturn attribute

2017-07-13 Thread Lurker via Digitalmars-d

On Saturday, 8 July 2017 at 20:27:11 UTC, H. S. Teoh wrote:
Also, a @noreturn attribute would allow overriding a non-void 
class method with a @noreturn one (e.g. the derived class is a 
sentinel object that forces an exception / termination upon 
calling that method), whereas you can't do that with a None 
return type because the signature would not match the base 
class's.



T


The reverse is also true, and more disastrous!


Re: proposed @noreturn attribute

2017-07-13 Thread Timon Gehr via Digitalmars-d

On Thursday, 13 July 2017 at 17:25:18 UTC, Timon Gehr wrote:
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.

...


(Actually, there are some complications like the .sizeof 
property. Anyway, it is clear what the semantics of Bottom are, 
no matter whether it is subtyping or implicit conversion.)


Re: proposed @noreturn attribute

2017-07-13 Thread Timon Gehr via Digitalmars-d
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.





Re: proposed @noreturn attribute

2017-07-12 Thread Andrei Alexandrescu via Digitalmars-d

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.



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".


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. 
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.


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?



Andrei


Re: proposed @noreturn attribute

2017-07-12 Thread Meta via Digitalmars-d

On Wednesday, 12 July 2017 at 09:32:32 UTC, 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.


D is not ML or Haskell or Idris. Rust has trod this ground before 
us and they saw it prudent to not make ! a first-class type. I 
think this is both a concession to usability and an acceptable 
compromise for a systems programming language.


Re: proposed @noreturn attribute

2017-07-12 Thread Timon Gehr via Digitalmars-d

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.


Re: proposed @noreturn attribute

2017-07-12 Thread Timon Gehr via Digitalmars-d

On 11.07.2017 19:27, Meta wrote:

On Tuesday, 11 July 2017 at 08:29:12 UTC, Timon Gehr wrote:

On 10.07.2017 18:23, Meta wrote:

...
problems with stuff like typeof(null)* etc. because for the most part 
it's just a regular type, unlike Bottom.


Bottom is just a regular type.


It's a regular type with unusual behaviour due to it being uninhabited.


All types are unusual. That does not mean they are not all types.


Re: proposed @noreturn attribute

2017-07-12 Thread Timon Gehr via Digitalmars-d

On 12.07.2017 03:50, Andrei Alexandrescu wrote:

On 7/11/17 4:29 AM, Timon Gehr wrote:

On 10.07.2017 18:23, Meta wrote:

...
problems with stuff like typeof(null)* etc. because for the most part 
it's just a regular type, unlike Bottom.


Bottom is just a regular type.


Wouldn't the fact that it's a subtype of all other types make it a bit 
more peculiar? -- Andrei


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.)


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.


In a very expressive type system, there are many more, functionally 
different types that are uninhabited, not just Bottom.


Re: proposed @noreturn attribute

2017-07-11 Thread Andrei Alexandrescu via Digitalmars-d

On 7/11/17 4:29 AM, Timon Gehr wrote:

On 10.07.2017 18:23, Meta wrote:

...
problems with stuff like typeof(null)* etc. because for the most part 
it's just a regular type, unlike Bottom.


Bottom is just a regular type.


Wouldn't the fact that it's a subtype of all other types make it a bit 
more peculiar? -- Andrei


Re: proposed @noreturn attribute

2017-07-11 Thread Random D user via Digitalmars-d
On Saturday, 8 July 2017 at 12:18:38 UTC, Andrei Alexandrescu 
wrote:

On 7/8/17 7:07 AM, bachmeier wrote:

On Saturday, 8 July 2017 at 10:15:39 UTC, Walter Bright wrote:


Having an @noreturn attribute will take care of that:

   @noreturn void ThisFunctionExits();


Why should this be an attribute rather than a pragma?


So it's part of the summary of the function. -- Andrei


If it feels like a pragma, should be part of the function and 
reflectable, then how about:


void assertFalse(bool cond) @pragma(noreturn)

or

void assertFalse(bool cond) @pragma("noreturn")

The compiler could probably give an error if the "" (inside 
@pragma) wasn't a known string.
Also @pragma would be useful as standard way of saying "special 
compiler attribute". No need to consume global attribute 
namespace.


I'm expecting to see @myproject_safe and @myproject_noreturn type 
of attributes someday in some project :|


Re: proposed @noreturn attribute

2017-07-11 Thread Meta via Digitalmars-d
On Monday, 10 July 2017 at 20:00:10 UTC, Steven Schveighoffer 
wrote:
This means that you get errors for some instantiations. Which 
ironically means you'd need to do something like this:


void foo(alias f)()
{
   f();
   static if(!isNoreturn!f)
   {
   auto a = 5;
   ...// etc.
   }
}

Today, it's not a big issue. We can't alias `assert` function 
directly, so it's obvious where it's an assert or not (because 
you have to spell it out!).


We have similar problems today with generic code causing 
unreachability errors. See for instance 
https://issues.dlang.org/show_bug.cgi?id=14835


-Steve


I think that for our own sanity the dead-code check would have to 
be disabled in this case. I agree that it'd be awful putting 
`static if (!isNoReturn!f)` everywhere.


Actually, why not just disable it entirely in templated functions?


Re: proposed @noreturn attribute

2017-07-11 Thread Meta via Digitalmars-d

On Tuesday, 11 July 2017 at 08:29:12 UTC, Timon Gehr wrote:

On 10.07.2017 18:23, Meta wrote:

...
problems with stuff like typeof(null)* etc. because for the 
most part it's just a regular type, unlike Bottom.


Bottom is just a regular type.


It's a regular type with unusual behaviour due to it being 
uninhabited.


Re: proposed @noreturn attribute

2017-07-11 Thread Timon Gehr via Digitalmars-d

On 10.07.2017 04:44, Walter Bright wrote:

Let's call the bottom type 'B' for the moment, for convenience.

If we think of it like a floating point NaN,


It's not. It's an empty type.

then any type construction 
of B yields a B:


 const(B) -> B


I don't see why to add this special case.


 B* -> B
 B[] -> B
 X[B] -> B
 B[X] -> B
...


This would be wrong. All of the types on the left have valid values, 
they are not isomorphic to B.


Since B cannot have a value, any expression that forms a B can be 
replaced with an assert(0).


 B foo(); // declaration
 foo() -> foo(); assert(0);



Yes.



 cast(B)exp -> exp; assert(0);

 B b; -> assert(0);



Those wouldn't compile. (Nothing can be cast to bottom, there is no 
default initializer that the variable declaration can use.)



Given a tuple of types:

 alias T = tuple(B,X);

is T equivalent to which of:

 B   (1)
 tuple(X)(2)
 tuple(Y,X)  (3)
 tuple(B,X)  (4)

? I'm leaning toward (4) as making the most sense.
...


It's the only one that makes any sense.


 struct S {
T t;
 }

should then yield an error, while:

 struct S {
T[1..1] t; // t is of type X
 }

would not.


I guess you meant T[1..2].


Re: proposed @noreturn attribute

2017-07-11 Thread Timon Gehr via Digitalmars-d

On 10.07.2017 18:23, Meta wrote:

...
problems with stuff like typeof(null)* etc. because for the most part 
it's just a regular type, unlike Bottom.


Bottom is just a regular type.


Re: proposed @noreturn attribute

2017-07-11 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-11 09:37, Iain Buclaw via Digitalmars-d wrote:


Right, you can't put noreturn on enforce itself, but you can on the
internal bailOut function called by enforce.


Ah, but I though it would just contain a "throw" for the case the the 
condition is false. I see now that it doesn't.


--
/Jacob Carlborg


Re: proposed @noreturn attribute

2017-07-11 Thread Rainer Schuetze via Digitalmars-d



On 08.07.2017 12:15, Walter Bright wrote:
C compilers (and by extension C++ compilers) usually have an extension 
which allows a function to be marked as one that never returns. The 
point of this is it enables improved data flow analysis and better code 
being generated.


Noreturn functions crop up in things like assert's and enforce's. DMD 
internally hardcodes a few functions it knows about that are noreturn, 
and the DMD optimizer and codegen take advantage of it.


But when people write their own assert's and enforce's, this falls 
apart. While the programs will still work, they won't be as efficient as 
they could be.


Having an @noreturn attribute will take care of that:

@noreturn void ThisFunctionExits();

Yes, it's another builtin attribute and attributes are arguably a 
failure in language design.


I don't like the inflation of attributes, too, but encoding it into the 
return type seems too clever, especially when having to explain it again 
and again to people without functional language background (like me).


A few questions inspired from discussion in 
https://github.com/dlang/druntime/pull/1839:


- Does @noreturn need to be inferred for templates?

void msgAssert(bool cond)(string msg)
{
debug writeln(msg);
assert(cond);
}

- The template function above is (strongly) pure, how does @noreturn 
interact with that? Will @noreturn ensure it is not elided?


- If it does, how does this propagate to a function calling it, e.g.

   void c_assert(bool cond, string msg) pure
   {
   if (!cond)
   msgAssert!false(msg);
   }

A call to c_assert can be elided according to the pure rules. Any chance 
that this can be avoided with the help of @noreturn?


Re: proposed @noreturn attribute

2017-07-11 Thread Iain Buclaw via Digitalmars-d
On 11 July 2017 at 08:46, Jacob Carlborg via Digitalmars-d
 wrote:
> On 2017-07-10 22:00, Walter Bright wrote:
>
>> Yes. Not having it makes enforce(), for example, generate poor code.
>
>
> Not sure I understand. "enforce" will return if the condition is true.
>

Right, you can't put noreturn on enforce itself, but you can on the
internal bailOut function called by enforce.


Re: proposed @noreturn attribute

2017-07-11 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-10 22:00, Walter Bright wrote:


Yes. Not having it makes enforce(), for example, generate poor code.


Not sure I understand. "enforce" will return if the condition is true.

--
/Jacob Carlborg


Re: proposed @noreturn attribute

2017-07-10 Thread Marco Leise via Digitalmars-d
Am Sat, 8 Jul 2017 03:15:39 -0700
schrieb Walter Bright :

> […]
>
> Having an @noreturn attribute will take care of that:
> 
> @noreturn void ThisFunctionExits();
> 
> Yes, it's another builtin attribute and attributes are arguably a failure in 
> language design.

The 'none' return type sounds interesting, because a @noreturn
function is also a void function, it is practical to implement
this as a void sub-type or compiler recognized druntime
defined "type intrinsic". On the other hand, the attribute
solution has worked well for the existing compilers in practice
and such a rarely used tag doesn't add significantly to the
meticulous D programmers list: "pure @safe nothrow @nogc".

-- 
Marco



Re: proposed @noreturn attribute

2017-07-10 Thread Walter Bright via Digitalmars-d

On 7/10/2017 12:02 PM, Jacob Carlborg wrote:

Are those few cases worth optimizing for?


Yes. Not having it makes enforce(), for example, generate poor code.



Re: proposed @noreturn attribute

2017-07-10 Thread Steven Schveighoffer via Digitalmars-d

On 7/10/17 3:05 PM, Meta wrote:

On Monday, 10 July 2017 at 18:50:54 UTC, Steven Schveighoffer wrote:

On 7/10/17 2:38 PM, Walter Bright wrote:

On 7/10/2017 4:00 AM, Steven Schveighoffer wrote:
But I have to ask, what is the benefit of statically determining 
that a function is noreturn?


It is useful anywhere dataflow analysis is useful.

FunctionThatDoesnotReturn();
a = b; // error: unreachable code


That doesn't require static introspection. The compiler can see that, 
the user doesn't have to worry about it.


Note, one thing that hasn't been mentioned is how we are now going to 
be able to make regular functions noreturn. This means templates that 
accept aliases will now have to deal with the possibility that those 
aliases are noreturn.


So if the compiler, for instance, marks the above as an error, what 
happens here?


foo(alias f)()
{
   f();
   auto a = b;
}

if f is a noreturn function, is this instantiation an error?


Currently not. This is either a bug or the compiler's flow analysis is 
not robust enough to detect this case.


I think the implication from Walter is that f would be treated just like 
a direct call to assert(0) (i.e. it doesn't return).


So where code like this produces an "unreachable statement" error:

void foo()
{
   assert(0);
   auto a = b;
}

with dmd -w, code like the above will potentially produce an unreachable 
code error if f is a noreturn (the compiler can now do dataflow analysis 
and determine it's unreachable).


This means that you get errors for some instantiations. Which ironically 
means you'd need to do something like this:


void foo(alias f)()
{
   f();
   static if(!isNoreturn!f)
   {
   auto a = 5;
   ...// etc.
   }
}

Today, it's not a big issue. We can't alias `assert` function directly, 
so it's obvious where it's an assert or not (because you have to spell 
it out!).


We have similar problems today with generic code causing unreachability 
errors. See for instance https://issues.dlang.org/show_bug.cgi?id=14835


-Steve


Re: proposed @noreturn attribute

2017-07-10 Thread Walter Bright via Digitalmars-d

On 7/10/2017 12:05 PM, Meta wrote:
Currently not. This is either a bug or the compiler's flow analysis is not 
robust enough to detect this case.


Flow analysis relies on the function's signature, not its implementation, and 
currently the signature contains no information about noreturn.


Addressing this is the whole point of this thread.


Re: proposed @noreturn attribute

2017-07-10 Thread ketmar via Digitalmars-d

Jacob Carlborg wrote:

I'm going to ask the stupid question: I understand that this is for the 
compiler to generate better code. But, since the attribute (or whatever 
it is) indicates that a function won't return, it can only be used in 
very few cases. Are those few cases worth optimizing for?


the case that makes @noreturn worth having is even not optimizing, but 
don't adding visual noise at the call site.


case Smth: error("boo");
case Other: ...

oops. i know that `error()` will never return, but compiler doesn't, and 
insisting on adding `break;` there.


sure, i can either put break, or always put `assert(0);` after noreturn 
functions, but hey, aren't we invented computers exactly to lay off such 
borning things onto them!? ;-)


Re: proposed @noreturn attribute

2017-07-10 Thread Patrick Schluter via Digitalmars-d

On Monday, 10 July 2017 at 18:09:54 UTC, H. S. Teoh wrote:
On Sun, Jul 09, 2017 at 02:49:35PM -0400, Nick Sabalausky 
(Abscissa) via Digitalmars-d wrote:

On 07/09/2017 06:51 AM, Daniel N wrote:
> On Sunday, 9 July 2017 at 10:31:47 UTC, Mr.D wrote:
> > On Saturday, 8 July 2017 at 10:15:39 UTC, Walter Bright 
> > wrote:
> > 
> > > Has anyone a better idea?
> > 
> > What about
> > 
> > scope(exit) assert(0);
> > 
> > ?
> 
> void func()

> out { assert(0); }
> body
> {
> }

Too indirect and verbose. An attribute or special "return 
type" would just cut straight to the case.


If DIP 1009 is accepted, this would not be verbose at all:

void func()
out(false) // it even tells you it won't return
{
...
}

Plus, this has the advantage that you can specify a valid 
return type for when you need to override a base class method, 
e.g.:


class JitCompiler {
Code compile(string code);
}
class InvalidCompiler : JitCompiler {
override Code compile(string code) out(false) {...}
}

A Bottom type that implicitly converts to anything would also 
fit the bill, granted, but does require changing the language.


The main thing I have against adding a Bottom type is that it 
adds yet another built-in type to the language, which means (1) 
a combinatorial explosion of existing language constructs 
combined with the new type, with currently-unknown consequences 
(and possibly corner cases we haven't thought of that will come 
back to bite us), (2) yet another special type newcomers have 
to learn with special semantics (I can already anticipate 
complaints to D.learn about what's the difference between null 
and bottom); (3) having to implement lots of compiler changes 
to handle how this new type interacts with operators and other 
types in all possible cases; (4) all of this just for something 
that (a) is only rarely used, and (b) could have been easily 
implemented by adding @noreturn or using existing contract 
syntax without adding a whole new basic type to the language.


Honestly, I'd vote for @noreturn as the simplest, most 
straightforward solution, and the only reason I'm arguing for 
out{assert(0);} (or out(false) if DIP 1009 is accepted) is 
because people are all up in arms about adding Gosh Yet Another 
Special UDA In Addition To The Numerous Special UDAs We Already 
Have Like @safe and @nogc.



+1



Re: proposed @noreturn attribute

2017-07-10 Thread Meta via Digitalmars-d
On Monday, 10 July 2017 at 18:50:54 UTC, Steven Schveighoffer 
wrote:

On 7/10/17 2:38 PM, Walter Bright wrote:

On 7/10/2017 4:00 AM, Steven Schveighoffer wrote:
But I have to ask, what is the benefit of statically 
determining that a function is noreturn?


It is useful anywhere dataflow analysis is useful.

FunctionThatDoesnotReturn();
a = b; // error: unreachable code


That doesn't require static introspection. The compiler can see 
that, the user doesn't have to worry about it.


Note, one thing that hasn't been mentioned is how we are now 
going to be able to make regular functions noreturn. This means 
templates that accept aliases will now have to deal with the 
possibility that those aliases are noreturn.


So if the compiler, for instance, marks the above as an error, 
what happens here?


foo(alias f)()
{
   f();
   auto a = b;
}

if f is a noreturn function, is this instantiation an error?


Currently not. This is either a bug or the compiler's flow 
analysis is not robust enough to detect this case.


int b;

auto foo(alias f)()
{
f();
auto a = b; //no unreachable code error
}

void main()
{
foo!(() => assert(0))();
}




Re: proposed @noreturn attribute

2017-07-10 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-08 12:15, Walter Bright wrote:

C compilers (and by extension C++ compilers) usually have an extension
which allows a function to be marked as one that never returns. The
point of this is it enables improved data flow analysis and better code
being generated.

Noreturn functions crop up in things like assert's and enforce's. DMD
internally hardcodes a few functions it knows about that are noreturn,
and the DMD optimizer and codegen take advantage of it.

But when people write their own assert's and enforce's, this falls
apart. While the programs will still work, they won't be as efficient as
they could be.


I'm going to ask the stupid question: I understand that this is for the 
compiler to generate better code. But, since the attribute (or whatever 
it is) indicates that a function won't return, it can only be used in 
very few cases. Are those few cases worth optimizing for?


--
/Jacob Carlborg


Re: proposed @noreturn attribute

2017-07-10 Thread Steven Schveighoffer via Digitalmars-d

On 7/10/17 2:38 PM, Walter Bright wrote:

On 7/10/2017 4:00 AM, Steven Schveighoffer wrote:
But I have to ask, what is the benefit of statically determining that 
a function is noreturn?


It is useful anywhere dataflow analysis is useful.

FunctionThatDoesnotReturn();
a = b; // error: unreachable code


That doesn't require static introspection. The compiler can see that, 
the user doesn't have to worry about it.


Note, one thing that hasn't been mentioned is how we are now going to be 
able to make regular functions noreturn. This means templates that 
accept aliases will now have to deal with the possibility that those 
aliases are noreturn.


So if the compiler, for instance, marks the above as an error, what 
happens here?


foo(alias f)()
{
   f();
   auto a = b;
}

if f is a noreturn function, is this instantiation an error? That's 
going to get messy. It's not a problem today, because you can't alias 
`assert`, and the compiler doesn't care about other functions that don't 
return (even if they are completely available).


I learned the hard way with inout not to proactively make obvious errors 
errors. For instance, you can't return inout if you don't have any inout 
parameters. It makes complete logical sense when you think about it, 
just use const. This leads to the (inout int = 0) crap we see everywhere 
in phobos.


-Steve


Re: proposed @noreturn attribute

2017-07-10 Thread Walter Bright via Digitalmars-d

On 7/10/2017 4:00 AM, Steven Schveighoffer wrote:
But I have to ask, what is the benefit of statically determining that a function 
is noreturn?


It is useful anywhere dataflow analysis is useful.

   FunctionThatDoesnotReturn();
   a = b; // error: unreachable code


Re: proposed @noreturn attribute

2017-07-10 Thread H. S. Teoh via Digitalmars-d
On Sun, Jul 09, 2017 at 02:49:35PM -0400, Nick Sabalausky (Abscissa) via 
Digitalmars-d wrote:
> On 07/09/2017 06:51 AM, Daniel N wrote:
> > On Sunday, 9 July 2017 at 10:31:47 UTC, Mr.D wrote:
> > > On Saturday, 8 July 2017 at 10:15:39 UTC, Walter Bright wrote:
> > > 
> > > > Has anyone a better idea?
> > > 
> > > What about
> > > 
> > > scope(exit) assert(0);
> > > 
> > > ?
> > 
> > void func()
> > out { assert(0); }
> > body
> > {
> > }
> 
> Too indirect and verbose. An attribute or special "return type" would
> just cut straight to the case.

If DIP 1009 is accepted, this would not be verbose at all:

void func()
out(false) // it even tells you it won't return
{
...
}

Plus, this has the advantage that you can specify a valid return type
for when you need to override a base class method, e.g.:

class JitCompiler {
Code compile(string code);
}
class InvalidCompiler : JitCompiler {
override Code compile(string code) out(false) {...}
}

A Bottom type that implicitly converts to anything would also fit the
bill, granted, but does require changing the language.

The main thing I have against adding a Bottom type is that it adds yet
another built-in type to the language, which means (1) a combinatorial
explosion of existing language constructs combined with the new type,
with currently-unknown consequences (and possibly corner cases we
haven't thought of that will come back to bite us), (2) yet another
special type newcomers have to learn with special semantics (I can
already anticipate complaints to D.learn about what's the difference
between null and bottom); (3) having to implement lots of compiler
changes to handle how this new type interacts with operators and other
types in all possible cases; (4) all of this just for something that (a)
is only rarely used, and (b) could have been easily implemented by
adding @noreturn or using existing contract syntax without adding a
whole new basic type to the language.

Honestly, I'd vote for @noreturn as the simplest, most straightforward
solution, and the only reason I'm arguing for out{assert(0);} (or
out(false) if DIP 1009 is accepted) is because people are all up in arms
about adding Gosh Yet Another Special UDA In Addition To The Numerous
Special UDAs We Already Have Like @safe and @nogc.


T

-- 
The diminished 7th chord is the most flexible and fear-instilling chord. Use it 
often, use it unsparingly, to subdue your listeners into submission!


  1   2   >