fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
346 stars 21 forks source link

Use `static` and access modifiers for a group of class members simultaneously #1268

Open konst-sh opened 1 year ago

konst-sh commented 1 year ago

**I propose we allow to use access modifiers and static for multiple member declarations at once like this:

    type Test () =
        static
            let x = 0
            member a = 1
            member b = 2
        private
            member _.c() = "private member"
            member _.d() = "another one"

**The existing way of approaching this problem in F# is to use keyword in every declaration separately

Pros and Cons

**The advantages of making this adjustment to F# are less verbose class declaration, especially useful when you only have to use a class as container for function definitions because of exclusive class features like overloads, optional arguments, setters/getters, members with different access mode can be visually separated into blocks of definitions.

**The disadvantages of making this adjustment to F# are - some extra work on compiler - all I can think of.

Extra information

**Estimated cost (XS, S, M, L, XL, XXL): S

Affidavit (please submit!)

Please tick this by placing a cross in the box:

Please tick all that apply:

For Readers

If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.

Happypig375 commented 1 year ago

How about one step further

    type Test () =
        static
            let x = 0
            member
                a = 1
                b = 2
        member private _.
            c() = "private member"
            d() = "another one"
konst-sh commented 1 year ago

@Happypig375 I thought about this, but I think that is already too much substructuring. My idea was to make it similar to do block, keeping current member definition syntax. The static block looks special from this point, its a step to making less verbose full static class definition

BentTranberg commented 1 year ago

How will you deal with this existing valid code? I don't know what the definition of breaking change is, but I will guess this suggestion is a breaking change. Doesn't mean it's not possible. Not that I'm in favor - I'm not. Technically less verbose - yes. Easier to read - no. Not with two alternative ways that will compete for your attention. Let's stick to one way. People coming from C# will be familiar with the existing syntax - modifiers on each member separately.

type Test() =
    static
        member Test1() = ()
        member _.Test2() = ()
       member _.Test3() = ()
      member _.Test4() = ()
     member _.Test5() = ()
    member _.Test6() = ()
konst-sh commented 1 year ago

@BentTranberg Interesting example, if some object member definition is found in the scope of the static block it can be allowed with warning, so this will not be a breaking change, but will enforce some good formatting practice.

Happypig375 commented 1 year ago

Then probably parentheses could do

    type Test () =
        static (
            let x = 0
            member
                a = 1
                b = 2
        )
        member private _.(
            c() = "private member"
            d() = "another one"
        )
charlesroddie commented 1 year ago

Not with two alternative ways that will compete for your attention. Let's stick to one way. People coming from C# will be familiar with the existing syntax - modifiers on each member separately.

Agreed

LyndonGingerich commented 1 year ago

I think that this proposal is not a good idea.

How would this change handle members with multiple modifiers? Could you create member groups with multiple modifiers?

    type Test () =
        static private
            let x = 0
            member a = 1
            member b = 2

What about nested member groups?

    type Test () =
        static
            let x = 0
            member a = 1
            member b = 2
            private
                member _.c() = "private member"
                member _.d() = "another one"
konst-sh commented 1 year ago

@LyndonGingerich I agree with your first point, regarding navigation in classes with long lists of members - when we consciously acknowledge that sometimes its inevitable - that might be up to the IDE to track the scope of the cursor. Regarding the member structuring that will be encouraged with this change - I would feel uneasy also in case if I would find a static member between the object members or a private members randomly alternating with public ones. I don't like the idea to allow deep sub-structuring of these modifiers, a one level of additional structure should be enough. Combining few modifiers to make a group looks to me like the best outcome. Thanks for your points.