F# naming convention

2020-08-09 07:43发布

问题:

Is there an "official" naming / casing convention for F#?

I'm always in doubt of using C# style or not:

Class.MyFunctionName or Module.my_function_name

In F# you're meant to mix BCL classes and F# library ones: they have different casing and the code looks very ugly.

回答1:

Yes, there is confusion, because F# has morphed from OCaml to .Net over the years. Basically, the naming conventions are a "breaking change" - old code is inconsistent with new code.

However, the May 2009 CTP has settled the issue.

The Release Notes say...

Standard Library Naming Conventions

The naming conventions adopted for the F# library are as follows:

  • All .NET and F# OO code uses PascalCase according to existing .NET guidelines

  • The F# functional programming operators such as List.map are for use in F# internal implementation code. This kind of code uses camelCase for operator names

  • Underscores should not be used.

So, your question...

Class.MyFunctionName or Module.my_function_name 

The answer is

Class.MyFunctionName and Module.MyFunctionName (but see edit below!)

(applying rule 1 above).

-- Edit. Nov 2, 2019 --

The current guidelines recommend camelCase for functions at module level, so it's

Module.myFunctionName

Which then makes production code consistent with the F# libraries (eg. List.averageBy)



回答2:

Anything official: I think "not quite yet", but whenever VS 2010 reaches Beta1 you'll probably see the F# library in its nearly-final form, and there will be a number of renamings relative to the CTP. F# will probably always be a little more schizophrenic than its older .NET cousins, given its history.



回答3:

I think the answer might have changed since the time of the currently accepted answer.

The F# Style Guide today says:

Use PascalCase for type declarations, members, and labels

Classes, interfaces, structs, enumerations, delegates, records, and discriminated unions should all be named with PascalCase. Members within types and labels for records and discriminated unions should also use PascalCase.

type IMyInterface =
    abstract Something: int

type MyClass() =
    member this.MyMethod(x, y) = x + y

type MyRecord = { IntVal: int; StringVal: string }

type SchoolPerson =
    | Professor
    | Student
    | Advisor
    | Administrator

https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#use-pascalcase-for-type-declarations-members-and-labels

and

Use camelCase for module-bound public functions

When a module-bound function is part of a public API, it should use camelCase: F#

module MyAPI =
    let publicFunctionOne param1 param2 param2 = ...

    let publicFunctionTwo param1 param2 param3 = ...

https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#use-camelcase-for-module-bound-public-functions

So, based on those, my answer is that this:

Class.MyFunctionName 
Module.my_function_name 

Should be written like this:

Class.MyFunctionName  
Module.myFunctionName 


回答4:

My understanding and current usage is that module/static functions have lower case, and 'instance' functions have upper case.

Edit not an answer to this question, but related: F# Formatting conventions by Don Syme



回答5:

From what I've seen from hubfs.com and other sources, its a mix from .net and OCaml.

I hope they switch to either one and not have two different conventions and being Microsoft i am sure they will go with the dot net style.



回答6:

Not sure there is any real solution. It seems that perhaps OCaml-ish code might retain some of its naming, i.e., lowercase module methods, whereas OO members will go .NET style.