dlang.org icon indicating copy to clipboard operation
dlang.org copied to clipboard

Formatting and Wording of Main/CMain

Open Bolpat opened this issue 1 year ago • 8 comments

In particular, replace “must be declared” by “is typically declared,” as many variants are possible.

Bolpat avatar Jul 05 '24 10:07 Bolpat

Thanks for your pull request and interest in making D better, @Bolpat! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

dlang-bot avatar Jul 05 '24 10:07 dlang-bot

The specification should be exact. If there are valid main signatures missing, they should be added.

dkorpel avatar Jul 05 '24 10:07 dkorpel

The specification should be exact.

Agreed.

If there are valid main signatures missing, they should be added.

Trying to be absolutely technically correct with grammar here would be madness. The reason is that there are simply too many syntactic ways to express the main function semantically correctly.

  1. The return type, if present,
    • can be an Identifier which is an alias in-effect to void, int, or noreturn;
    • can also be a typeof(Expression) if the Expression has one of the allowed types;
    • can be an enum type that is backed by int;
    • can be any of the above with const or immutable qualifiers attached.
  2. The parameter, if present,
    • need not be named;
    • in practice, may have any qualified version of char[][];
    • may have storage classes;
    • may have its whole declaration be an alias.

My best take:

MainFunction:
    StorageClasses? MainReturnType main MainParameters? FunctionAttributes? MainFunctionBody
    StorageClasses main MainParameters? FunctionAttributes? MainFunctionBody

MainReturnType:
    MainReturnBasicType
    TypeCtor ( TypeCtors? MainReturnBasicType )

MainReturnBasicType:
    void
    int
    Identifier

MainParameters:
    ( MainParameter )
    ( MainParameter , )

MainParameter:
    MainParameterDeclaration
    MainParameterDeclaration = AssignExpression

MainParameterDeclaration:
    ParameterAttributes? MainParameterBasicType MainParameterTypeSuffixes? Identifier?

MainParameterBasicType:
    char
    TypeCtor ( TypeCtors? MainParameterBasicType MainParameterTypeSuffixes? )
    Identifier

MainParameterTypeSuffixes:
    [ ]
    [ ] [ ]

MainFunctionBody:
    SpecifiedFunctionBody
    ShortenedFunctionBody

(Essentially, I ended up repeating the FuncDeclaration grammar, pruning it where it can’t be semantically correct.)

The Identifier in MainReturnType must be an alias to void, int, or noreturn, or an enum backed by int — that is near-impossible to express with syntax.

In MainParameterDeclaration, the MainParameterBasicType and MainParameterTypeSuffixes must agree to produce a type that is semantically a dynamic array or dynamic array of char, qualified in any shape or form, including mutable, inout, and shared.

For some reason, the parameter of main can have a default argument, but not be var-arg.

The fact that the parameter type can both be char[][] and string[] is wild. The only way this can be right is if the backing array is indeed mutable and converts to string[] because it’s unique.

Doing the above again for the extern(C) main function:

CMainFunction:
    StorageClasses? extern ( C ) StorageClasses? MainReturnType main CMainParameters? FunctionAttributes? MainFunctionBody

CMainParameters:
    CMainParameterList
    CMainParameterList ,

CMainParameterList:
    CMainFirstParameter , CMainNextParameter
    CMainFirstParameter , CMainNextParameter , CMainNextParameter

CMainFirstParameter:
    CMainFirstParameterDeclaration
    CMainFirstParameterDeclaration = AssignExpression

CMainNextParameter:
    CMainNextParameterDeclaration
    CMainNextParameterDeclaration = AssignExpression

CMainFirstParameterDeclaration:
    ParameterAttributes? CMainFirstParameterBasicType Identifier?

CMainFirstParameterBasicType:
    int
    TypeCtor ( TypeCtors? CMainFirstParameterBasicType )
    Identifier

CMainNextParameterDeclaration:
    ParameterAttributes? CMainNextParameterBasicType CMainParameterTypeSuffixes? Identifier?

CMainNextParameterBasicType:
    char
    TypeCtor ( TypeCtors? MainParameterBasicType CMainParameterTypeSuffixes? )
    Identifier

CMainParameterTypeSuffixes:
    *
    * *

I’ll translate that into the DDoc syntax if you think that’s valuable. Otherwise I’d rather remove the grammar part and just explain the declaration with prose.

Bolpat avatar Jul 05 '24 13:07 Bolpat

Nice comprehensive analysis! I wouldn't make the grammar more complex but I wouldn't completely remove it either, the current grammar strikes a nice balance. The variations can be explained in prose like this:

"Other formulations that result in a main with the same or a covariant function type as one of the above are also allowed."

I think that covers all variations, barring the type string[] and char[][] being both allowed.

The only way this can be right is if the backing array is indeed mutable and converts to string[] because it’s unique.

I think those are both the case, so the spec could mention it's a char[][] that's considered unique so it may convert to string[].

dkorpel avatar Jul 05 '24 13:07 dkorpel

@ntrel, this should be good to go. Please have a look and if it’s good, merge.

Bolpat avatar Jul 15 '24 11:07 Bolpat

I prefer Dennis's suggestion, I think that's clearer.

(I don't have merge rights).

ntrel avatar Jul 15 '24 19:07 ntrel

The current formulation:

The main function must have either no parameters or a single parameter. If provided, the parameter must be a possibly qualified version of char[][], and can optionally have the ParameterAttributes in, return or scope. It is customary to use immutable(char)[][], i.e. string[], but, in particular char[][] is also allowed. The argument passed to a main function with parameter is mutable and unique, which is why it converts to immutable, inout, or shared.

What exactly do you want to replace by “Other formulations that result in a main with the same or a covariant function type as one of the above are also allowed.”?

Bolpat avatar Jul 16 '24 09:07 Bolpat

I think that sentences can be appended without replacing existing sentences in that paragraph.

dkorpel avatar Jul 29 '24 12:07 dkorpel