January 18, 2022
On 17.01.22 20:39, H. S. Teoh wrote:
> What kind of special cases, specifically?  Making variables of type
> noreturn illegal does not preclude taking parameters of type noreturn.
> Most current generic code does tests of the form:
> 
> 	template someTpl(T)
> 	if (is(typeof((T t) {
> 			... // tests on t here
> 		})))
> 	{ ... }
> 
> This wouldn't be affected by the fact that T may be noreturn. If the
> generic function actually needs to instantiate a variable of type T,
> then it*should*  be a compile error when T is noreturn anyway (because
> it can't possibly do anything meaningful with such a variable, and the
> fact that instantiation wasn't prevented means there's a logic error
> somewhere).

+1. Exactly what I was wondering about too.
January 18, 2022
On 17.01.22 20:39, H. S. Teoh wrote:
> Making variables of type noreturn illegal

Variables of type `noreturn` should certainly remain legal, perhaps just not default initialization of such variables.

> does not preclude taking parameters of type noreturn

Sometimes it would, but it should not. E.g., this is fine:

noreturn foo(noreturn x){
    auto y=x;
    return y;
}
January 18, 2022
On Tue, Jan 18, 2022 at 12:55:06AM +0100, Timon Gehr via Digitalmars-d wrote:
> On 17.01.22 20:39, H. S. Teoh wrote:
> > Making variables of type noreturn illegal
> 
> Variables of type `noreturn` should certainly remain legal, perhaps just not default initialization of such variables.
> 
> > does not preclude taking parameters of type noreturn
> 
> Sometimes it would, but it should not. E.g., this is fine:
> 
> noreturn foo(noreturn x){
>     auto y=x;
>     return y;
> }

Hmm. This again treads that default-initialization / manual initialization fine line.  I can see why such a thing would be useful (e.g., you pass a throwing (i.e., noreturn) predicate to a range function and expect that it should still compile and run), but having to special-case it seems to go against the entire point of having a noreturn type.

Now I'm also lost as to what the "right" behaviour ought to be. :-D


T

-- 
They pretend to pay us, and we pretend to work. -- Russian saying
January 18, 2022
On 1/18/22 19:02, H. S. Teoh wrote:
> On Tue, Jan 18, 2022 at 12:55:06AM +0100, Timon Gehr via Digitalmars-d wrote:
>> On 17.01.22 20:39, H. S. Teoh wrote:
>>> Making variables of type noreturn illegal
>>
>> Variables of type `noreturn` should certainly remain legal, perhaps
>> just not default initialization of such variables.
>>
>>> does not preclude taking parameters of type noreturn
>>
>> Sometimes it would, but it should not. E.g., this is fine:
>>
>> noreturn foo(noreturn x){
>>      auto y=x;
>>      return y;
>> }
> 
> Hmm. This again treads that default-initialization / manual
> initialization fine line.

I am not creating any values, I am taking them from the caller. Execution already can't reach that variable.

> I can see why such a thing would be useful
> (e.g., you pass a throwing (i.e., noreturn) predicate to a range
> function and expect that it should still compile and run), but having to
> special-case it seems to go against the entire point of having a
> noreturn type.
> ...


I don't understand where you see a special case here. Disallowing `noreturn` locals would be the special case.


> Now I'm also lost as to what the "right" behaviour ought to be. :-D
> 
> 
> T
> 

There is no single "right" behaviour due to the prevalence of ad-hoc rules in D semantics. I guess if the compiler can show that the code is unreachable, then it can default initialize anything, but just allowing threading though the non-existent value itself is probably sufficient.
February 05, 2022
On Monday, 17 January 2022 at 16:11:03 UTC, Timon Gehr wrote:
> On 16.01.22 23:56, Max Samukha wrote:
>> On Saturday, 15 January 2022 at 18:35:02 UTC, Paul Backus wrote:
>>>
>>> Technically, a variable is a name associated with a block of memory, which may or may not contain a value. In the case of `noreturn`, the block of memory has size 0, and there are no possible values it can contain.
>> 
>> Memory of size 0 contains a single value, which is the value of the unit type, 0-tuple, or whatever. Zero type is different. Timon, I am totally confused, could you clarify?
>> ...
>
> I share your confusion. A block of memory of size zero indeed has a unique value, not zero values. I don't think there is any principled way to arrive at a semantics where the program survives an attempt to initialize a `noreturn` variable. Also, note that typically, if a type `A*` is a subtype of a type `B*`, then `A.sizeof>=B.sizeof`. `noreturn*` is a subtype of any `T*`. Hence, `noreturn.sizeof` should be at least `size_t.max` or even `∞`. Thus, `noreturn.sizeof == 0` is already a special case with a pragmatic justification and using it to attempt to justify any further behavior of `noreturn` is questionable in the first place.
>
>>>
>>> So, technically, a `noreturn` variable is impossible to initialize. But since the compiler knows that the behavior of the program can't possibly depend on the variable's value, it is free to just skip the initialization altogether and leave the variable uninitialized instead.
>> 
>> Sounds like "alias x = noreturn.init;"
>> 
>>>
>>> I guess you could make an argument that you should have to write `noreturn x = void;` every time you declare a `noreturn` variable. But even then, it would not be correct for `noreturn x;` to result in an `assert(0)` at runtime--it would have to be a *compile-time* error.
>> 
>> I think it depends on the definition of local declaration. For statics, it is obviously a compile-time error. For locals, my feeling is it should be a runtime error, but who knows. Timon, help.
>
> In D, types that do not have a default constructor cannot be default-constructed. The question is whether `noreturn`, the empty type, should really have a default constructor (that immediately terminates the program). As far as I understand, according to the DIP, `noreturn` has a default constructor, but `noreturn` variables are initialized lazily when they are accessed. I am not sure whether that's pragmatically the right choice, because it's a special case and generic code might check whether some type is default-constructible and only in this case declare a local variable of that type. At least it crashes at the latest possible moment, I guess. It's certainly a bit weird that now, in D, 0·x is not always 0.

Thanks, Timon! Don't construe the lack of a reply as disrespect. I'm slow, uneducated and still thinking.
1 2 3 4 5
Next ›   Last »