CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
F# Coding Guidelines
Code should be either
"#light" code (without in/;; etc.); or
"neutral" code that doesn't give warnings when "#light" is added
Recommendation: Use 4-space indentation. If using Visual Studio set the "Tab" setting for F# code editing to 4-space and "replace tabs by spaces"
let myFunction x y =
let g z =
let q = z * z
x + y + z + q
let w = x + y + g 3
(x,y,w)
Recommendation: Consider aligning constructs vertically, especially when polishing code, but not when rapid-prototyping:
Recommendation: use trailing closing token for records, lists and arrays normally on end of line of last construct
let rainbow =
let rainbow =
Not everyone likes this style, and variation is OK. For large constructs (> 6 lines) the closing token can be on a fresh line:
let rainbow =
Note: you can optionally include a trailing ";" for the last entry
Recommendation: Tuples that split across multiple lines follow a similar rule:
let tree1 =
Binary_node
(Binary_node(Binary_value , Binary_value ),
Binary_node(Binary_value , Binary_value ))
However the following is also acceptable:
let tree1 =
Binary_node(
Binary_node(Binary_value , Binary_value ),
Binary_node(Binary_value , Binary_value )
Recommendation: Arrays that split across multiple lines follow a similar rule:
let pascals_triangle =
[| [| |];
; |];
; ; |];
; ; ; |];
; ; ; ; |];
; ; ; ; ; |];
; ; ; ; ; ; |];
; ; ; ; ; ; ; |];
; ; ; ; ; ; ; ; |];
Recommendation: Always use at least one space between two distinct parantherical operators (e.g. leave a space after a "[" and between a "[" and a "{")
Not:
Recommendation: Note these are essentially never needed in #light code. However, if a begin/end is included then either dangle or indent
e.g.
if not file.Exists then
begin
Idioms.using
(file.CreateText())
(fun stream ->
stream.WriteLine('hello world'))
end;
or
if not file.Exists then begin
Idioms.using
(file.CreateText())
(fun stream ->
stream.WriteLine('hello world'))
end;
or use #light:
#light
if not file.Exists then
Idioms.using (file.CreateText()) (fun stream ->
stream.WriteLine 'hello world')
but not
if not file.Exists then
begin
Idioms.using
(file.CreateText())
(fun stream ->
stream.WriteLine('hello world'))
end;
or
if not file.Exists then
begin
Idioms.using
(file.CreateText())
(fun stream ->
stream.WriteLine('hello world'))
end;
Recommendation: Within object expressions, with/and line up underneath "new"
Recommendation: Strongly consider the "member" syntax for object expression members. This is a relatively new addition to the language, so many samples don't use it.
Recommendation: if interfaces supported then align these and format "with"/"and" in the same way
let the_players =
Another example:
let comparer =
not
let comparer =
Recommendation: Rules of a pattern match should be aligned with "match". Rules of a "with" in a "try"/"with" can be optionally 4-space indented:
e.g.
try
if System.DateTime.Now.Second % 3 = 0 then
raise (new System.Exception())
else
raise (new System.ApplicationException())
with
| :? System.ApplicationException ->
print_endline 'A second that was not a multiple of 3'
| _ ->
print_endline 'A second that was a multiple of 3'
but this is also OK:
try
if System.DateTime.Now.Second % 3 = 0 then
raise (new System.Exception())
else
raise (new System.ApplicationException())
with
| :? System.ApplicationException ->
print_endline 'A second that was not a multiple of 3'
| _ ->
print_endline 'A second that was a multiple of 3'
Recommendation: Use a "|" for each clause of a match (strictly speaking it is optional for the first), except when the match is all on one line.
OK:
match l with
| :: tail -> x
| _ :: tail -> find_david tail
| [] -> failwith 'Couldn't find David'
Not:
match l with
| :: tail -> x
| _ :: tail -> find_david tail
| [] -> failwith 'Couldn't find David'
OK:
match l with [] -> false | _ :: _ -> true
Recommendation: arguments always indented from functions
OK:
(Printf.sprintf 't%s - %inr'
x.ingredient_name x.quantity) )
OK:
(Printf.sprintf
't%s - %inr'
x.ingredient_name x.quantity))
OK:
let print_volumes x =
Printf.printf 'Volume in liters = %f, in us pints = %f, in imperial = %f'
(convert_volume_to_liter x)
(convert_volume_us_pint x)
(convert_volume_imperial_pint x)
Not:
let print_volumes x =
Printf.printf 'Volume in liters = %f, in us pints = %f, in imperial = %f'
(convert_volume_to_liter x)
(convert_volume_us_pint x)
(convert_volume_imperial_pint x)
Not:
(Printf.sprintf 't%s - %inr'
x.ingredient_name x.quantity) )
Recommendation: infix expressions are ok to lineup on same column
OK:
acc +
(Printf.sprintf 't%s - %inr'
x.ingredient_name x.quantity) )
Recommendation: function arguments (e.g. to Add, Iterate, ForEach etc.) can be either on next line or with a dangling "fun" on the argument line:
OK:
toggle.Click.Add(fun _ ->
if !eventAdded then
event.Click.RemoveHandler(stuffHandler)
else
event.Click.AddHandler(stuffHandler);
eventAdded := not !eventAdded;
setText eventAdded);
Tolerable:
toggle.Click.Add(
fun _ ->
if !eventAdded then
event.Click.RemoveHandler(stuffHandler)
else
event.Click.AddHandler(stuffHandler);
eventAdded := not !eventAdded;
set_text eventAdded);
Recommendation: In general no space is used after a data constructor if arguments are parenthesized:
OK: BinaryNode
Not: BinaryNode
OK:
Idioms.using (file.CreateText()) (fun stream ->
stream.WriteLine('hello world'))
OK:
Idioms.using
(file.CreateText
"arg1"
"arg2")
(fun stream ->
stream.WriteLine('hello world'))
Recommendation: Multi-line definitions where a token is on the same line as an "=" should either be fully indented past the point of the "="
let couples = [ ;
;
;
]
But not:
let couples = [ ;
;
;
]
And not:
let couples =
[ ;
;
;
]
Recommendation: Pipeline |> should go at the start of a line immediately under the expression being operated on:
OK:
let methods2 = System.AppDomain.CurrentDomain.GetAssemblies()
|> List.of_array
|> List.map ( fun assm -> assm.GetTypes() )
|> Array.concat
|> List.of_array
|> List.map ( fun t -> t.GetMethods() )
|> Array.concat
OK:
let methods2 =
System.AppDomain.CurrentDomain.GetAssemblies
|> List.of_array
|> List.map ( fun assm -> assm.GetTypes() )
|> Array.concat
|> List.of_array
|> List.map ( fun t -> t.GetMethods() )
|> Array.concat
Not:
let methods2 = System.AppDomain.CurrentDomain.GetAssemblies()
|> List.of_array
|> List.map ( fun assm -> assm.GetTypes() )
|> Array.concat
|> List.of_array
|> List.map ( fun t -> t.GetMethods() )
|> Array.concat
TBD
Recommendation: Indent "|" in type definition by 4 spaces:
OK:
type volume =
| Liter of float
| USPint of float
| ImperialPint of float
Not:
type volume =
| Liter of float
| USPpint of float
| ImperialPint of float
The following operators are defined in the F# standard library and should be used wherever possible instead of defining equivalents. This is spelled out explicitly because OCaml doesn't support all of these operators, and thus F# users who have first learnt OCaml are often not aware of this.
f >> g -- forward composition
g << f -- reverse composition
x |> f -- forward pipeline
f <| x -- reverse pipeline
x |> ignore -- throwing away a value
x + y -- overloaded addition (including string concatenation)
x - y -- overloaded subtraction
x * y -- overloaded multiplication
x / y -- overloaded division
x % y -- overloaded modulus
x <<< y -- bitwise left shift
x >>> y -- bitwise right shift
x ||| y -- bitwise left shift
x &&& y -- bitwise right shift
x ^^^ y -- bitwise left shift
x && y -- lazy/short-cut 'and'
x || y -- lazy/short-cut 'or'
Use comprehensions, but be aware of their limitations (e.g. you can't do a 'fold').
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 625
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved