Git Product home page Git Product logo

Comments (27)

auduchinok avatar auduchinok commented on May 26, 2024

Unnecessary breaking of namespaces into separate lines should be avoided.

From the syntax tree view it's not possible to distinguish a namespace from a static member or a module member access. How it should probably be formulated is try to maintain line breaks inside expressions with dot access and only split them for parts that don't fit on line with current line length settings.

Mutation of an object should still be preferred as the only action on that line

I'd say the same thing here: we should try to keep the original formatting choice for places where the style guide allows variations like this.

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

Decision on (4) is here: #663

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

On (2) I agree, ideally we should never break namespaces, I think under any circumstances. However it will be difficult to implement because namespaces are not known to fantomas. I don't know how we could implement except a list of known namespaces. And really, good code should open the namespace.

Overall I think we could say this fits under "bad code formats badly"

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

On (3) I'm torn, it's not a simple choice. I'm aware it is a realy problem in practice. There is also a major risk of being inconsistent with functions and methods taking tupled paramters.

The current guidance is here: https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#formatting-function-and-member-arguments

We must also consider the variaitons.

One indent (4-space) - current style guide

let curried:

let sillyfuncWithParams 
    parameterName1
    ignoredParameterName2 
    ignoredParameterName3 =
    ...

let tupled:

let sillyfuncWithParams 
    (
        parameterName1,
        ignoredParameterName2,
        ignoredParameterName3
    ) =
    ...

let mixed:

let sillyfuncWithParams 
    parameterName0
    (
        parameterName1,
        ignoredParameterName2,
        ignoredParameterName3
    )
    parameterName4 =
    ...

let rec curried:

let rec sillyfuncWithParams 
    parameterName1
    ignoredParameterName2 
    ignoredParameterName3 =
    ...

let rec tupled:

let rec sillyfuncWithParams 
    (
        parameterName1,
        ignoredParameterName2,
        ignoredParameterName3
    ) =
    ...

let private curried:

let private sillyfuncWithParams 
    parameterName1
    ignoredParameterName2 
    ignoredParameterName3 =
    ...

let private tupled:

let private sillyfuncWithParams 
    (
        parameterName1,
        ignoredParameterName2,
        ignoredParameterName3
    ) =
    ...

static member curried:

type C() =
    static member sillyfuncWithParams 
        parameterName1
        ignoredParameterName2 
        ignoredParameterName3 =
    ...

static member tupled:

type C() =
    static member sillyfuncWithParams 
        (
            parameterName1,
            ignoredParameterName2,
            ignoredParameterName3
        ) =
    ...

Two indent (8-space)

let curried:

let sillyfuncWithParams 
        parameterName1
        ignoredParameterName2 
        ignoredParameterName3 =
    ...

let tupled:

let sillyfuncWithParams 
        (
            parameterName1,
            ignoredParameterName2, 
            ignoredParameterName3
        ) =
    ...

let mixed:

let sillyfuncWithParams 
        parameterName0
        (
            parameterName1,
            ignoredParameterName2, 
            ignoredParameterName3
        )
        parameterName4 =
    ...

let rec curried

let rec sillyfuncWithParams 
        parameterName1
        ignoredParameterName2 
        ignoredParameterName3 =
    ...

let rec tupled

let rec sillyfuncWithParams 
        (
            parameterName1,
            ignoredParameterName2,
            ignoredParameterName3
        ) =
    ...

let private curried

let private sillyfuncWithParams 
        parameterName1
        ignoredParameterName2 
        ignoredParameterName3 =
    ...

let private tupled

let private sillyfuncWithParams 
        (
            parameterName1,
            ignoredParameterName2,
            ignoredParameterName3
        ) =
    ...

static member curried:

type C() =
    static member sillyfuncWithParams 
            parameterName1
            ignoredParameterName2 
            ignoredParameterName3 =
    ...

static member tupled:

type C() =
    static member sillyfuncWithParams
           ( 
                parameterName1,
                ignoredParameterName2,
                ignoredParameterName3
            ) =
    ...

from fslang-design.

auduchinok avatar auduchinok commented on May 26, 2024

@dsyme We've been using that double-indent approach in ReSharper.FSharp and I haven't seen cases where it wouldn't work well. It always makes it very clear where a function/method/type body begins.

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

@auduchinok I've added tupled and mixed cases to the above. What do you think for static members? And is there any reason that case would be different?

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

@auduchinok basically it seems it is only curried let that's a problem for single-indentation, because of the unfortuanate exact alignment between function name and curried arguments. But of course it's the most common case as well.

The question is would we use double-indentation for all of the above? Or just the let cases? Or let the single plain let? and would we use double indentation for tupled argument lists? And mixed?

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

I've repurposed this issue to be specifically about formatting of argument lists

from fslang-design.

auduchinok avatar auduchinok commented on May 26, 2024

@auduchinok I've added tupled and mixed cases to the above. What do you think for static members? And is there any reason that case would be different?

It could be something like that (i.e. follow the expression rules and keep the opening paren on the previous line):

type C() =
    static member sillyfuncWithParams( 
            parameterName1,
            ignoredParameterName2,
            ignoredParameterName3) =
        ...

In our project I'd format it like this:

type C() =
    static member sillyfuncWithParams(parameterName1, ignoredParameterName2,
            ignoredParameterName3) =
        ...

or (to add a constructor example)

type C(parameterName1, ignoredParameterName2,
        ignoredParameterName3) =
    static member sillyfuncWithParams(parameterName1, ignoredParameterName2,
            ignoredParameterName3) =
        ...

from fslang-design.

dsyme avatar dsyme commented on May 26, 2024

It's interesting to note that currently this mixed example:

let sillyfuncWithParams
    parameterName0
    (parameterName1,
     ignoredParameterName2,
     ignoredParameterName3,
     ignoredParameterName4,
     ignoredParameterName5,
     ignoredParameterName6)
    =
    1

formats the tuple portion differently to

let sillyfuncWithParams
    (
        parameterName1,
        ignoredParameterName2,
        ignoredParameterName3,
        ignoredParameterName4,
        ignoredParameterName5,
        ignoredParameterName6
    ) =
    1

@nojaf what's the currently implemented rule here? Is treating things taking one tuple of arguments as special?

from fslang-design.

nojaf avatar nojaf commented on May 26, 2024

@dsyme I believe the mixed example never came up in the style guide before.
We only seem to add the indentation when there is a single tuple parameter.

from fslang-design.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.