{"action":"created","issue":{"url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/1068","labels_url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/1068/labels{/name}","comments_url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/1068/comments","events_url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/1068/events","html_url":"https://github.com/fsprojects/VisualFSharpPowerTools/issues/1068","id":99467127,"number":1068,"title":"Formatter overly opinionated, enforces intent-clobbering F# style","user":{"login":"bryanedds","id":1625560,"avatar_url":"https://avatars.githubusercontent.com/u/1625560?v=3","gravatar_id":"","url":"https://api.github.com/users/bryanedds","html_url":"https://github.com/bryanedds","followers_url":"https://api.github.com/users/bryanedds/followers","following_url":"https://api.github.com/users/bryanedds/following{/other_user}","gists_url":"https://api.github.com/users/bryanedds/gists{/gist_id}","starred_url":"https://api.github.com/users/bryanedds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bryanedds/subscriptions","organizations_url":"https://api.github.com/users/bryanedds/orgs","repos_url":"https://api.github.com/users/bryanedds/repos","events_url":"https://api.github.com/users/bryanedds/events{/privacy}","received_events_url":"https://api.github.com/users/bryanedds/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-08-06T15:52:26Z","updated_at":"2015-08-06T20:05:16Z","closed_at":null,"body":"Myself and a few others at Jet are adopting an F# coding standard. Unfortunately, the formatter actively works against this standard, even though the standard was specifically designed to be enforceable by just such a tool. Not only are the default settings of the format opinionated such that it fights against this style, there are no options in many cases to align its behavior with said style (or any other than the default!)\r\n\r\nThis should really be fixed so that we can actually use the formatter like we could in C# (where the default C# formatter was actually nearly perfect to match most professional C# standards, rather than the one the author of the tool seemed to personally prefer).\r\n\r\nFor more concrete info, here are the portions of the code standard that relate to F# formatting -\r\n\r\n\r\nA) Correctness\r\n\r\n\r\n14) Prefix option bindings as well as bindings to potentially null values with 'opt'.\r\n\r\n15) Prefix choice bindings with 'chc'.\r\n\r\n16) Prefix functions that return an option or potential null with 'try', or another such indicator like 'getOpt'.\r\n\r\n17) Prefix functions that return a choice with 'attempt', or another such indicator like 'getChc'.\r\n\r\n\r\nB) Consistency\r\n\r\n\r\n3) Use the standard F# naming conventions by -\r\n\r\n    using UpperCamelCasing for Namespaces, Modules, Types, Fields, Constants, Properties, and InstanceMembers (but as said above, avoid authoring Properties and InstanceMembers in the first place).\r\n    using lowerCamelCasing for variables, functions, staticMembers, parameters, and 'typeParameters.\r\n\r\n6) Place 'open' statements at the top of each file, right below the current namespace declaration (if any).\r\n\r\n9) Prefer stepped indentation as it refactors better, keeps lines shorter, and keeps formatting normal and enforcible via automation. For example, write this -\r\n\r\n    let result =\r\n        ingest\r\n            apple\r\n            banana\r\n            caribou\r\n\r\nrather than this -\r\n\r\n    let result = ingest apple\r\n                        banana\r\n                        caribou\r\n\r\n\r\n10) F# is based on ML, which is more based on Lisp than C, so use Lisp-style bracing instead of C-style. For example, write this -\r\n\r\n    let ys =\r\n        [f x\r\n         g x\r\n         h x]\r\n\r\nrather than this -\r\n\r\n    let ys =\r\n        [\r\n            f x\r\n            g x\r\n            h x\r\n        ]\r\n\r\nand this -\r\n\r\n    type T =\r\n        { M : int\r\n          N : single }\r\n\r\nrather than this -\r\n\r\n    type T =\r\n        {\r\n          M : int\r\n          N : single\r\n        }\r\n\r\n\r\n11) Tab out discriminated union case definitions to keep them lined up with their members. For example, write this -\r\n\r\n    type T =\r\n        | A of int\r\n        | B of single\r\n        static member makeA i = A (i * 2)\r\n        static member makeB s = B (s * 2.0f)\r\n\r\nrather than this -\r\n\r\n    type T =\r\n    | A of int\r\n    | B of single\r\n        static member makeA i = A (i * 2)\r\n        static member makeB s = B (s * 2.0f)\r\n\r\n\r\n12) Handle the intentional case first when matching / if'ing -\r\n\r\n    let fn optValue =\r\n        match optValue with\r\n        | Some value -> // do what we actually intended to do in this function\r\n        | None -> // handle the missing case\r\n\r\n\r\n13) Surround tuples with parens to keep evaluation ordering and intent clear. For example, write this -\r\n\r\n    let (a, b) = (b, a)\r\n\r\nrather than this -\r\n\r\n    let a, b = b, a\r\n\r\n\r\n14) Conceptually, () is unit, so please treat it as such. For example, write 'fn ()' rather than 'fn()'.\r\n\r\n15) Conceptually, (a, b, c) is a tuple, so please treat it as such. For example, write 'fn (a, b, c)' rather than 'fn(a, b, c)'.\r\n\r\n\r\nD) And Generally...\r\n\r\n\r\n1) Use an automated code formatter to enforce this coding standard as much as possible. Note that this is a work-in-progress due to a lack of existing tooling for F#.\r\n\r\n2) When appending to this standard, prefer the style that is most enforcible by a reasonably intelligent automated code formatter."},"comment":{"url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/comments/128488861","html_url":"https://github.com/fsprojects/VisualFSharpPowerTools/issues/1068#issuecomment-128488861","issue_url":"https://api.github.com/repos/fsprojects/VisualFSharpPowerTools/issues/1068","id":128488861,"user":{"login":"bryanedds","id":1625560,"avatar_url":"https://avatars.githubusercontent.com/u/1625560?v=3","gravatar_id":"","url":"https://api.github.com/users/bryanedds","html_url":"https://github.com/bryanedds","followers_url":"https://api.github.com/users/bryanedds/followers","following_url":"https://api.github.com/users/bryanedds/following{/other_user}","gists_url":"https://api.github.com/users/bryanedds/gists{/gist_id}","starred_url":"https://api.github.com/users/bryanedds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bryanedds/subscriptions","organizations_url":"https://api.github.com/users/bryanedds/orgs","repos_url":"https://api.github.com/users/bryanedds/repos","events_url":"https://api.github.com/users/bryanedds/events{/privacy}","received_events_url":"https://api.github.com/users/bryanedds/received_events","type":"User","site_admin":false},"created_at":"2015-08-06T20:05:16Z","updated_at":"2015-08-06T20:05:16Z","body":"Can you assign me maintainership?"}}