Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider reordering and reorganizing sections #959

Open
BillWagner opened this issue Sep 29, 2023 · 16 comments
Open

Consider reordering and reorganizing sections #959

BillWagner opened this issue Sep 29, 2023 · 16 comments
Assignees
Milestone

Comments

@BillWagner
Copy link
Member

BillWagner commented Sep 29, 2023

Moving a couple ideas from an email thread here so we don't lose them

Currently the material for properties & indexers is organised as follows:

§15.7 Properties -> §15.7.2 Static and instance properties
Specification of properties
§15.7.3 Accessors -> §15.7.6 Virtual, sealed, override, and abstract accessors
Specification of accessors, shared by both properties and indexers. 15.7.3, 15.7.4 & 15.7.6, added by PR 837, have Notes explaining they are shared as they are written in terms of properties (by happenstance 15.7.5 is written in terms of both)
§15.8 Events
Specification of events
§15.9 Indexers -> §15.9.2 Indexer and Property Differences
Specification of indexers. 15.9.2 was added in PR 837 to bring the differences together at the end of 15.9

This is a bit mixed up and a little bit of shuffling may help. Having shared material being in subclauses of 15.7 seems wrong to me, but even just swapping Events & Indexers around so similar material is adjacent would help. Here is one possible shuffle:

§15.7 Properties -> §15.7.2 Static and instance properties
Specification of properties
§15.8 (prev 15.9) Indexers -> §15.8.2 (prev 15.9.2) Indexer and Property Differences
Specification of indexers
§15.9 Accessors
§15.9.1 General
The content of what is currently Notes on 15.7.3, 15.7.4 & 15.7.6
§15.9.2 (prev 15.7.3) Accessors -> §15.9.5 (prev 15.7.6) Virtual, sealed, override, and abstract accessors
Specification of accessors, shared by both properties and indexers.
§15.10 Events
Specification of events

And related note:

We currently define most aspects of all member function kinds in the Classes chapter, and enhance/restrict a few of those in the Structs chapter, and then again to a lesser extent in the Interfaces chapter. Coming soon in V8, we’ll be looking at PR #681, which adds support for default member function member implementations in interfaces for pretty much all member function kinds. As you will see from some of the proposed edits in that PR, I tried to deal with having the core definition of each given function member kind in the Classes chapter, and then amending/extending it in the others.

Taking this idea into account, does it make sense to put all the core member function details in a “Member functions” chapter, and have the Classes, Structs, Interfaces chapters point there, with each containing only supplemental information?

@BillWagner
Copy link
Member Author

@jskeet

I think we should decide if we want to do some of this work during the Pre-8 milestone.

@jskeet jskeet added this to the Pre-C# 8.0 milestone Oct 2, 2023
@jskeet jskeet added the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Oct 2, 2023
@jskeet
Copy link
Contributor

jskeet commented Oct 2, 2023

Yes, it would be good to get as much of this as we feel we can bite off done before we start applying new features. Let's talk about it at the meeting.

@RexJaeschke
Copy link
Contributor

RexJaeschke commented Oct 2, 2023

I thought about this a great deal as I was spec'ing PR #681. I finished up putting at the start of each section in the Classes chapter that introduced a new member kind, words to the effect that this description covers classes and structs, but the interfaces chapter had more to say.

From a cleanliness pov, pulling the core stuff in a separate chapter, "Member Functions" as Bill suggested, sounds like a fine idea. At the start of each member function section we could have a fixed-template-style statement something like:

This feature is supported by classes/structs/interfaces [[include those, as appropriate]]. The following description is augmented and/or constrained by its parent type in sections xx, yy, ..., and zz.

From a less-ideal pov, this would involve some non-trivial effort, the result of which would need some serious review to make sure errors were not introduced.

FYI, despite MS proposal's suggesting that a (V9) record is a new type, after discussion with Mads I've spec'd it as a qualified class type and in V10, a qualified struct type, so the reordering under discussion is not impacted by the addition of records.

While it's fine to discuss this as a Pre-V8 topic, I don't see that it should hold up V8 work.

@jskeet
Copy link
Contributor

jskeet commented Nov 1, 2023

Nigel is going to look at just the reordering aspect to see how feasible it is.
Bill will look for duplicated text for more information to feed into a discussion.

@BillWagner BillWagner self-assigned this Nov 1, 2023
@jskeet jskeet removed the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Nov 1, 2023
@RexJaeschke RexJaeschke changed the title Consider reording and reorganizing sections Consider reordering and reorganizing sections Nov 1, 2023
@BillWagner BillWagner added the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Feb 7, 2024
@BillWagner
Copy link
Member Author

Capturing notes from the 2/7 ECMA meeting:

We discussed introducing a "type members" chapter. One concern would be the impact on the grammar for class, struct, and interface. Currently, the grammar for those types are based on the definitions by starting with class and specifying differences for struct and interface, and the order they appear in the spec. This might have a major impact on how this could be done.

One potential could be to rely more on prose that describes constraints on the type definitions for class, struct, and interface. Maybe there's an abstract grammar for a "user defined type", and prose describes the restrictions for each specific type.

Also, consider two PRs: One for the first set of reshuffling proposed. Another to consider what a new Members chapter might look like, and what impact would be on class, struct and interface clauses, respectively.

@jskeet
Copy link
Contributor

jskeet commented Apr 18, 2024

Removing "meeting discuss" as I believe we know what's coming next.

@jskeet jskeet removed the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Apr 18, 2024
@RexJaeschke RexJaeschke self-assigned this Jun 4, 2024
@RexJaeschke
Copy link
Contributor

Heads up! I am taking a look at the idea of creating a separate "Type members" core chapter.

@RexJaeschke
Copy link
Contributor

The following assumes the new functionality provided by the V8 PR #681, “Adding support for default interface function members,” will be adopted.

Allowed Contexts for Each Kind of Member Declaration

Member Kind Class Struct Interface Notes
constant_declaration X X X
field_declaration X X X
method_declaration X X X
property_declaration X X X
event_declaration X X X
indexer_declaration X X X
operator_declaration X X X
constructor_declaration X X
static_constructor_declaration X X X
finalizer_declaration X
type_declaration X X X
fixed_size_buffer_declaration X unsafe code support

@RexJaeschke
Copy link
Contributor

Rex’s Current Thinking

Although I like the idea of splitting out the core stuff, there is no doubt in my mind that would take a lot of work, especially w.r.t talking about inheritance (as Bill pointed out in private), and identifying which of the introductory subclauses in the class, struct, and interface clauses (such as 15.3.5, “The new modifier,” and 15.3.6, “Access modifiers” in classes.md) should be moved to the core clause, and how their wording would need to be tweaked to do so. Then, a lot of cross-reference links would need to be updated. The practical question is, “Will the new, reorganized approach make it more logical and easier/simpler to find things?” Having now looked in detail at methods (the largest member kind w.r.t spec page count), I’m thinking the reorg will be hard to justify.

@RexJaeschke
Copy link
Contributor

Creating a New Clause

The initial suggestion was to call it “Member Functions;” however, classes, structs, and interfaces, all allow non-function members like constants, fields, and nested types, so restricting the clause to member functions doesn’t sound right. On the other hand, we want to exclude namespace members. For now, I’m calling it “Type members,” although “Core type members” might work, assuming we exclude finalizers (only in classes), maybe constructors (only in classes and structs), and fixed-size buffer declarations (only in structs, and then only in unsafe mode).

@RexJaeschke
Copy link
Contributor

Type Member Kind Model

X. Type Members [new clause]

X.1 General [new subclause]

Let us refer to the member declaration’s parent type category—class, struct, or interface—as that member’s declaration context.

For all [[core]] member kinds, this clause specifies each member kind with [[little or]] no regard to the context in which it is declared. This core description might be augmented or overridden in a subclause of a context-specific clause. Unless the context-specific clause states otherwise, the core specification applies to that context, as written in the core clause.

X.2-x Existing subclauses not specific to a particular member kind

For example:

  • 15.2.3 Type parameters
  • 15.2.5 Type parameter constraints
  • 15.3.5 The new modifier
  • 15.3.6 Access modifiers
  • 15.3.7 Constituent types
  • 15.3.8 Static and instance members

X.n Member kind 1 [new subclause]

This kind of member is permitted in a class_member_declaration, struct_member_declaration, and interface_member_declaration.

The following context-independent text goes here; in general, no using the words “class,” “struct,” or “interface”:

  1. Grammar and semantics.
  2. Examples: if they truly illustrate core information, even if the code is written inside a specific context (typically a class), put it here; otherwise, move context-specific examples to that context’s subclause. (In deciding this, make sure to keep any normative text and associated example together in the same subclause.

classes.md [existing subclause]

  • Option 1: The following text augments that in the corresponding core subclause xx. …
  • and/or Option 2: The following text overrides that in the corresponding core subclause xx. …
  • Option 3, if neither 1 or 2 apply: There is no context-specific text to add to this topic; the corresponding core subclause xx applies.

structs.md [existing subclause]

same as for classes.md

interfaces [existing subclause]

same as for classes.md>

X.n+1 Member kind 2 [new subclause]

Type Member Kind Model Example

Here is the model applied to constants: [The spec for this simple member kind can easily be massaged into the model; I start with it simply to demonstrate the model. The much more complicated member kinds will be methods and properties/indexers, and I’ll comment on methods later.]

X.n Constants [new subclause]

<<The contents of 15.4, “Constants” goes here, with a few, minor tweaks, one of which is shown below.>>

A constant is a classtype member that represents a constant value: a value that can be computed at compile-time. A constant_declaration introduces one or more constants of a given type.

classes.md

15.4 Constants

There is no context-specific text to add to this topic; the corresponding core subclause xx applies.

struct.md

16.x Constants [new subclause]

There is no context-specific text to add to this topic; the corresponding core subclause xx applies.

interfaces.md

18.x Constants

The following text augments that in the corresponding core subclause xx.
As a constant_declaration is considered to have a default implementation (§18.1), it is not part of the interface’s contract.

See §interface-static-constructors for information regarding the allocation and initialization of constants.

Note: See §interface-fields for an example of using various kinds of static members declared within an interface. end note

@RexJaeschke
Copy link
Contributor

Concerns about the Impact on Grammar

Bill wrote: … One concern would be the impact on the grammar for class, struct, and interface. Currently, the grammar for those types are based on the definitions by starting with class and specifying differences for struct and interface, and the order they appear in the spec. This might have a major impact on how this could be done.

Bill is suggesting a level of abstraction one level up from my thinking. My model leaves the top-level grammar for class, struct, and interface completely as is. These three rules currently end in the rules class_member_declaration, struct_member_declaration, and interface_member_declaration, respectively, each of which contains some or all of the member kinds that would be moved to the new core clause. All non-core stuff re these three contexts would stay in their current clauses.

With the addition of support for default interface function members in V8, we no longer have interface-specific grammar rules for methods, properties, events, and indexers. interface_member_declaration will now contain only rules from the core member kind set, so I don’t see any grammar-related issues.

@RexJaeschke
Copy link
Contributor

Methods

Below is a table of information I gathered from looking at all the text in classes.md, seeing which could/should go—in whole or in part—in the new core clause, and for core stuff, how do the struct and interface clauses current augment/override that.

classes.md Subclause Move to Core Comments
15.1 General No
15.2 Class declarations
15.2.1 General No
15.2.2 Class modifiers ? struct, interface, enum clauses point here
15.2.3 Type parameters All shared with struct and interface clauses
15.2.4 Class base specification No struct and interface clauses point here
15.2.5 Type parameter constraints All shared with struct and interface clauses
15.2.6 Class body No
15.2.7 Partial declarations All shared with struct and interface clauses
15.3 Class members
15.3.1 General No 16.3 contains, “Except for the differences noted in §16.4, the descriptions of class members provided in §15.3 through §15.12 apply to struct members as well.” The soon-to-be-revised interfaces.md has pointers to various member kind subclasses, and makes no such general statement.
15.3.2 The instance type No
15.3.3 Members of constructed types ? interface clause points here
15.3.4 Inheritance No
15.3.5 The new modifier All shared with various member kind subclauses
15.3.6 Access modifiers All shared with various member kind subclauses
15.3.7 Constituent types All
15.3.8 Static and instance members All shared with struct and interface clauses
15.3.9 Nested types All? shared with struct and interface clauses
15.3.10 Reserved member names All
15.4 Constants All
15.5 Fields All? struct clause augments heavily, interface clause augments some
15.6.* Methods Most Things to do with inheritance will need review, also extension methods
15.7 Properties All? shared with struct and interface clauses
15.8 Events All? shared with struct and interface clauses
15.9 Indexers All? shared with struct and interface clauses
15.10 Operators All? shared with struct and interface clauses
15.11 Instance constructors some shared with struct clause, but not interfaces
15.12 Static constructors All? shared with struct and interface clauses
15.13 Finalizers No class-specific member kind
15.14 Iterators All? can have them in structs and interfaces, right?
15.15 Async Functions All shared with struct and interface clauses

@RexJaeschke
Copy link
Contributor

In #959 (comment), Bill proposed a reorg of the subclauses in properties and indexers. I've just completed a detailed review of those sections, and I agree with his general approach. I especially like the idea of having the Accessibility and Virtual, etc. sections subordinate to Accessors.

I have one question: As the existing 15.7.4, "Automatically implemented properties" is property-specific, should that go in the Properties section rather than the Accessors section? I don't mind either way, but I don't see that this bit is sharable.

@RexJaeschke
Copy link
Contributor

@BillWagner Thus far, this issue has 2 (separable) parts: a small reorg of properties vs. indexers, and a large reorg of member kinds. I'd like to add a third: a small "reorg"/renaming of sections entirely within struct.md.

Currently, classes.md has a section for each member kind, and if my proposed V8 interface implementation PR organization is adopted, so too will interfaces.md. However, struct.md does not. If it did, that would not only mirror the other 2 chapters, it would help if we decide to create a separate core member kind chapter.

This might be as simple as renaming several existing sections:

16.4.8 Field initializers --> Fields
16.4.9 Constructors --> leave as is
16.4.10 Static constructors -- leave as is
16.4.11 Automatically implemented properties --> Properties

To completely mirror the other 2 chapters, one could also add other sections, such as "Fields" and "Methods," which would contain nothing more than "nothing extra to say over and above that in the corresponding class section." While that might seem frivolous, here's why I suggest it: mechanical searching of the md files. If you search the md files for any references to 15.5 (Fields) of 15.6 (Methods), you will not get a hit in struct.md, yet that chapter certainly has something to say about those member kinds. Unfortunately, this is "hidden away" in 16.3 as, “Except for the differences noted in §16.4, the descriptions of class members provided in §15.3 through §15.12 apply to struct members as well.” Saying that explicitly on a per-member kind will greatly aid reference searching.

@RexJaeschke RexJaeschke modified the milestones: Pre-C# 8.0, Parked Sep 5, 2024
@RexJaeschke
Copy link
Contributor

RexJaeschke commented Sep 5, 2024

After some discussion on the TG2 call of 2024-09-04, we agreed to park this, as future version feature specs (from MS and revised by Rex) already rely on the current organization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Slipped
Status: Slipped
Status: Slipped
Status: Slipped
Development

No branches or pull requests

4 participants