Jump to page: 1 25  
Page
Thread overview
bottom type as parameter or local variable, does that make sense?
Jan 14, 2022
WebFreak001
Jan 14, 2022
H. S. Teoh
Jan 14, 2022
vit
Jan 14, 2022
H. S. Teoh
Jan 14, 2022
bauss
Jan 14, 2022
Nick Treleaven
Jan 14, 2022
Paul Backus
Jan 14, 2022
H. S. Teoh
Jan 14, 2022
Timon Gehr
Jan 14, 2022
H. S. Teoh
Jan 14, 2022
Timon Gehr
Jan 15, 2022
Tejas
Jan 15, 2022
Timon Gehr
Jan 14, 2022
Max Samukha
Jan 15, 2022
Paul Backus
Jan 15, 2022
Max Samukha
Jan 15, 2022
Paul Backus
Jan 15, 2022
Max Samukha
Jan 15, 2022
Paul Backus
Jan 15, 2022
Max Samukha
Jan 15, 2022
Paul Backus
Jan 16, 2022
Max Samukha
Jan 17, 2022
Paul Backus
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Timon Gehr
Jan 17, 2022
Elronnd
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Elronnd
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Timon Gehr
Jan 17, 2022
Paul Backus
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Paul Backus
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Paul Backus
Jan 17, 2022
H. S. Teoh
Jan 17, 2022
Timon Gehr
Jan 17, 2022
Timon Gehr
Jan 18, 2022
H. S. Teoh
Jan 18, 2022
Timon Gehr
Feb 05, 2022
Max Samukha
Jan 14, 2022
Timon Gehr
Jan 14, 2022
Nick Treleaven
January 14, 2022

For example:

import std.stdio;

void foo(noreturn a)
{
    writeln("we got called!");
}

void bar()
{
    noreturn b;
    writeln("calling");
    foo(b);
}

void main()
{
    writeln("bar");
    bar();
    writeln("done");
}

Guess what it prints and reply to it on this thread. I think the result is pretty nonsensical.

Reveal: https://run.dlang.io/is/4SXQal

Should this usage be allowed? I would say not allowing it would make more sense.

Additionally if we don't allow it we could allow aliasing to it like:

deprecated("OldType is no longer supported, use NewType instead") alias OldType = noreturn;

and with that both add hint messages for users to migrate and not allow broken code to compile.

A sample for this would be libdparse, where the arguments of the visit functions determine which function is called, even if the argument isn't actually used or just ignored. The cases where the argument type is specified, but not used, do happen and migrating types there to force the user to rewrite code is currently not possible without completely removing the type.

January 14, 2022
On Fri, Jan 14, 2022 at 11:52:04AM +0000, WebFreak001 via Digitalmars-d wrote:
> ```d
[...]
> void bar()
> {
>     noreturn b;
>     writeln("calling");
>     foo(b);
> }
[...]
> ```

Wait, doesn't the DIP say that while declaring a variable of type `noreturn` is technically allowed, it should abort at runtime as soon as the variable is initialized?  Why is program actually running past that line??!


T

-- 
It only takes one twig to burn down a forest.
January 14, 2022

On Friday, 14 January 2022 at 13:58:38 UTC, H. S. Teoh wrote:

>

On Fri, Jan 14, 2022 at 11:52:04AM +0000, WebFreak001 via Digitalmars-d wrote:

>

[...]

>

void bar()
{
noreturn b;
writeln("calling");
foo(b);
}
[...]

Wait, doesn't the DIP say that while declaring a variable of type noreturn is technically allowed, it should abort at runtime as soon as the variable is initialized? Why is program actually running past that line??!

T

Whith explicit init it works like that:

import std.stdio;


    void main(){
        noreturn n = noreturn.init;
        writeln("bar");
    }

Print:

//Illegal instruction (core dumped)
January 14, 2022
On Fri, Jan 14, 2022 at 02:05:25PM +0000, vit via Digitalmars-d wrote:
> On Friday, 14 January 2022 at 13:58:38 UTC, H. S. Teoh wrote:
> > On Fri, Jan 14, 2022 at 11:52:04AM +0000, WebFreak001 via Digitalmars-d wrote:
> > > ```d
> > [...]
> > > void bar()
> > > {
> > >     noreturn b;
> > >     writeln("calling");
> > >     foo(b);
> > > }
> > [...]
> > > ```
> > 
> > Wait, doesn't the DIP say that while declaring a variable of type `noreturn` is technically allowed, it should abort at runtime as soon as the variable is initialized?  Why is program actually running past that line??!
[...]
> Whith explicit init it works like that:
> 
> ```d
> import std.stdio;
> 
> 
>     void main(){
>         noreturn n = noreturn.init;
>         writeln("bar");
>     }
> 
> ```
> Print:
> ```
> //Illegal instruction (core dumped)
> ```

IMO, that's a bug.  Implicit initialization of noreturn should behave exactly the same way as invoking noreturn.init explicitly.

Somebody should file a bug, if one hasn't been filed already.


T

-- 
We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
January 14, 2022
On Friday, 14 January 2022 at 15:07:13 UTC, H. S. Teoh wrote:
> On Fri, Jan 14, 2022 at 02:05:25PM +0000, vit via Digitalmars-d wrote:
>> On Friday, 14 January 2022 at 13:58:38 UTC, H. S. Teoh wrote:
>> > On Fri, Jan 14, 2022 at 11:52:04AM +0000, WebFreak001 via Digitalmars-d wrote:
>> > > ```d
>> > [...]
>> > > void bar()
>> > > {
>> > >     noreturn b;
>> > >     writeln("calling");
>> > >     foo(b);
>> > > }
>> > [...]
>> > > ```
>> > 
>> > Wait, doesn't the DIP say that while declaring a variable of type `noreturn` is technically allowed, it should abort at runtime as soon as the variable is initialized?  Why is program actually running past that line??!
> [...]
>> Whith explicit init it works like that:
>> 
>> ```d
>> import std.stdio;
>> 
>> 
>>     void main(){
>>         noreturn n = noreturn.init;
>>         writeln("bar");
>>     }
>> 
>> ```
>> Print:
>> ```
>> //Illegal instruction (core dumped)
>> ```
>
> IMO, that's a bug.  Implicit initialization of noreturn should behave exactly the same way as invoking noreturn.init explicitly.
>
> Somebody should file a bug, if one hasn't been filed already.
>
>
> T

Why is it even allowed, that's beyond my understanding?
January 14, 2022
On Friday, 14 January 2022 at 15:55:54 UTC, bauss wrote:
>
> Why is it even allowed, that's beyond my understanding?

So that generic code compiles when a type resolves to noreturn:
https://github.com/dlang/DIPs/blob/15081980cd393e21218da6836321ed37ebc48dd3/DIPs/DIP1034.md#interaction-with-other-language-features
January 14, 2022

On Friday, 14 January 2022 at 15:07:13 UTC, H. S. Teoh wrote:

>

On Fri, Jan 14, 2022 at 02:05:25PM +0000, vit via Digitalmars-d wrote:

>

On Friday, 14 January 2022 at 13:58:38 UTC, H. S. Teoh wrote:

>

On Fri, Jan 14, 2022 at 11:52:04AM +0000, WebFreak001 via Digitalmars-d wrote:
[...]

>
void bar()
{
    noreturn b;
    writeln("calling");
    foo(b);
}

[...]

Wait, doesn't the DIP say that while declaring a variable of type noreturn is technically allowed, it should abort at runtime as soon as the variable is initialized? Why is program actually running past that line??!
[...]
Whith explicit init it works like that:

import std.stdio;


    void main(){
        noreturn n = noreturn.init;
        writeln("bar");
    }

Print:

//Illegal instruction (core dumped)

IMO, that's a bug. Implicit initialization of noreturn should behave exactly the same way as invoking noreturn.init explicitly.

Somebody should file a bug, if one hasn't been filed already.

That's not what the bug is here. noreturn is the type of expressions whose evaluation does not halt; i.e., it is a type with no values. Therefore, declaring a variable of type noreturn is a no-op: all it does is add a symbol to the current scope. No initialization is performed, because there is nothing to initialize.

On the other hand, this also means that any attempt to evaluate a noreturn expression (such as noreturn.init) can never succeed. So, a function call expression with a noreturn argument can never result in the function actually being called: it must either enter an infinite loop, throw an exception, terminate the program, etc.

Some noreturn expressions, like throw new Exception and () { while(1) {} }(), already had specific runtime behaviors defined by the language spec. Others, like noreturn.init, did not. For the latter kind of noreturn expression, the DIP specifies that their behavior at runtime is equivalent to assert(0).

January 14, 2022
On 1/14/22 12:52, WebFreak001 wrote:
> For example:
> ```d
> import std.stdio;
> 
> void foo(noreturn a)
> {
>      writeln("we got called!");
> }
> 
> void bar()
> {
>      noreturn b;
>      writeln("calling");
>      foo(b);
> }
> 
> void main()
> {
>      writeln("bar");
>      bar();
>      writeln("done");
> }
> ```
> 
> Guess what it prints and reply to it on this thread. I think the result is pretty nonsensical.
> 
> Reveal: https://run.dlang.io/is/4SXQal
> 
> Should this usage be allowed? I would say not allowing it would make more sense.

Debatable, but I think you have misidentified the questionable construct. I think the only question here is whether `noreturn` should have default construction. Maybe not. It should certainly be allowed as the type of a parameter or local variable, as avoiding that kind of special case is more or less the point of the feature.
January 14, 2022
On Fri, Jan 14, 2022 at 04:32:22PM +0000, Paul Backus via Digitalmars-d wrote:
> On Friday, 14 January 2022 at 15:07:13 UTC, H. S. Teoh wrote:
[...]
> > IMO, that's a bug.  Implicit initialization of noreturn should behave exactly the same way as invoking noreturn.init explicitly.
> > 
> > Somebody should file a bug, if one hasn't been filed already.
> 
> That's not what the bug is here. `noreturn` is the type of expressions whose evaluation does not halt; i.e., it is a type with no values. Therefore, declaring a variable of type `noreturn` is a no-op: all it does is add a symbol to the current scope. No initialization is performed, because there is nothing to initialize.

But in D, whenever a variable is declared, it gets initialized to its default value unless specified otherwise. Since nothing is specified here, it ought to perform its default initialization, and since there is no value with which it can be initialized, it ought to raise a runtime exception.


> On the other hand, this also means that any attempt to *evaluate* a `noreturn` *expression* (such as `noreturn.init`) can never succeed. So, a function call expression with a `noreturn` argument can never result in the function actually being called: it must either enter an infinite loop, throw an exception, terminate the program, etc.

In this case, the function never gets called, just as you said. But neither does it enter an infinite loop, throw an exception, or terminate the program.  So IMO there's definitely a bug here.


> Some `noreturn` expressions, like `throw new Exception` and `() {
> while(1) {} }()`, already had specific runtime behaviors defined by
> the language spec. Others, like `noreturn.init`, did not. For the
> latter kind of `noreturn` expression, the DIP specifies that their
> behavior at runtime is equivalent to `assert(0)`.

The `b` in `foo(b)` is an expression; the act of evaluating that
expression (in the course of calling foo) ought to terminate the program
with an assert(0). But it currently doesn't.  So it must be a bug.


T

-- 
Philosophy: how to make a career out of daydreaming.
January 14, 2022
On 1/14/22 18:41, H. S. Teoh wrote:
> But in D, whenever a variable is declared, it gets initialized to its
> default value unless specified otherwise. Since nothing is specified
> here, it ought to perform its default initialization, and since there is
> no value with which it can be initialized, it ought to raise a runtime
> exception.

I don't follow why this is necessarily desirable. E.g., if generic code checks whether or not a type can be default constructed, it will by default get a spurious "yes" answer and has to special case `noreturn`.
« First   ‹ Prev
1 2 3 4 5