Thread overview
A valid function with no return type?
Sep 24, 2020
Max Haughton
Sep 24, 2020
Adam D. Ruppe
Sep 24, 2020
Max Haughton
Sep 24, 2020
Meta
Sep 24, 2020
Stefan Koch
Sep 25, 2020
Meta
September 24, 2020
https://issues.dlang.org/show_bug.cgi?id=12638

https://run.dlang.io/is/jkEIiI

ref foo() {}

void main()
{
    import std.traits;
    pragma(msg, ReturnType!foo);
    foo();
}

Assuming this is supposed to be allowed by the standard, replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.
September 24, 2020
On Thursday, 24 September 2020 at 21:26:30 UTC, Max Haughton wrote:
> Assuming this is supposed to be allowed by the standard,

Yes, this is expected.

So the `auto` keyword in D is actually a do-nothing placeholder. It just indicates to the grammar that a declaration is coming. Any other keyword that is only valid in declarations does the same job and then implies `auto`.

In local variables it is often common to see like

const a = 5;

And in function declarations, a variety of things triggers the same thing including pure, ref, @safe, or even user-defined attributes. Just enough to tell the compiler a function is coming, then it assumes `auto` return until it sees a concrete type instead.

> replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.

main is special, it must have a specific signature to be registered.
September 24, 2020
On Thursday, 24 September 2020 at 21:26:30 UTC, Max Haughton wrote:
> https://issues.dlang.org/show_bug.cgi?id=12638
>
> https://run.dlang.io/is/jkEIiI
>
> ref foo() {}
>
> void main()
> {
>     import std.traits;
>     pragma(msg, ReturnType!foo);
>     foo();
> }
>
> Assuming this is supposed to be allowed by the standard, replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.

Anything other than `void main()`, `void main(string[] args)`, `int main()`, `int main(string[] args)` will cause the compiler report a compile error. It's probably special-cased in the compiler somewhere.
September 24, 2020
On Thursday, 24 September 2020 at 21:32:20 UTC, Meta wrote:
> On Thursday, 24 September 2020 at 21:26:30 UTC, Max Haughton wrote:
>> https://issues.dlang.org/show_bug.cgi?id=12638
>>
>> https://run.dlang.io/is/jkEIiI
>>
>> ref foo() {}
>>
>> void main()
>> {
>>     import std.traits;
>>     pragma(msg, ReturnType!foo);
>>     foo();
>> }
>>
>> Assuming this is supposed to be allowed by the standard, replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.
>
> Anything other than `void main()`, `void main(string[] args)`, `int main()`, `int main(string[] args)` will cause the compiler report a compile error. It's probably special-cased in the compiler somewhere.

Actually that's wrong.
The compiler will happily accept any number of qualifiers you stick on your main.
September 24, 2020
On Thursday, 24 September 2020 at 21:31:27 UTC, Adam D. Ruppe wrote:
> On Thursday, 24 September 2020 at 21:26:30 UTC, Max Haughton wrote:
>> Assuming this is supposed to be allowed by the standard,
>
> Yes, this is expected.
>
> So the `auto` keyword in D is actually a do-nothing placeholder. It just indicates to the grammar that a declaration is coming. Any other keyword that is only valid in declarations does the same job and then implies `auto`.
>
> In local variables it is often common to see like
>
> const a = 5;
>
> And in function declarations, a variety of things triggers the same thing including pure, ref, @safe, or even user-defined attributes. Just enough to tell the compiler a function is coming, then it assumes `auto` return until it sees a concrete type instead.
>
>> replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.
>
> main is special, it must have a specific signature to be registered.

Main will still compile if you indirect the return type through a template i.e. YourFavouriteMixin!"int" main(), whereas it doesn't get inferred at all for ref main (ref int main() {} gets through to regular sema)

Even if this behaviour is OK in the standard it still gives me the heebie-jeebies.
September 25, 2020
On Thursday, 24 September 2020 at 21:39:18 UTC, Stefan Koch wrote:
> On Thursday, 24 September 2020 at 21:32:20 UTC, Meta wrote:
>> On Thursday, 24 September 2020 at 21:26:30 UTC, Max Haughton wrote:
>>> https://issues.dlang.org/show_bug.cgi?id=12638
>>>
>>> https://run.dlang.io/is/jkEIiI
>>>
>>> ref foo() {}
>>>
>>> void main()
>>> {
>>>     import std.traits;
>>>     pragma(msg, ReturnType!foo);
>>>     foo();
>>> }
>>>
>>> Assuming this is supposed to be allowed by the standard, replacing void with ref (i.e. ref main { ) does not compile which suggests something isn't right.
>>
>> Anything other than `void main()`, `void main(string[] args)`, `int main()`, `int main(string[] args)` will cause the compiler report a compile error. It's probably special-cased in the compiler somewhere.
>
> Actually that's wrong.
> The compiler will happily accept any number of qualifiers you stick on your main.

Qualifiers yes but not return types/storage classes, isn't it? `ref` here is not a qualifier on the function; it's specifying the storage class for the return type.

September 25, 2020
On Friday, 25 September 2020 at 02:45:16 UTC, Meta wrote:

> Qualifiers yes but not return types/storage classes, isn't it? `ref` here is not a qualifier on the function; it's specifying the storage class for the return type.

This is a restriction not from the language, but from the caller of main - the system.
If you have a system that could interpret more complicated return values from a program, it would be no problem to allow such in the language. But at least for the systems I know (posix, windows, macOS) this is not the case.