This style guide details the formatting and styling of Daml and client-side code that is contained within this repository.
- Use 2 spaces for indentation
- Use single empty line to separate sections (and end the file with a single empty line)
- Use at most 100 characters per line. As a visual guide, you can add
"editor.rulers": [100]
to your vscodesettings.json
.
-
Order imports alphabetically with upper-case before lower-case:
import DA.Set (empty) import Daml.Script
-
Use qualified imports for interface modules:
import Daml.Finance.Interface.Asset.Holding qualified as Holding (view, I, V)
-
Use explicit imports and order them alphabetically:
In case of no name clashes, use unqualified imports:
import DA.Set (empty, fromList, singleton)
and otherwise qualified imports:
import DA.Map qualified as M (fromList) import DA.Set qualified as S (fromList, null)
- Only use explicit export lists when not all types or functions in a given module are exported
- Use the
-- | HIDE
annotation for anything that is not exported - Do add comments for types and functions that are not exported
- If you want an internal function to be tested individually, add it to the export list but
annotate it with the
-- | HIDE
comment.
-
Modules use the following newlines:
module Foo.Bar where import A.B.C import A.B.D template Baz with ... template Baz2 with ...
-
Templates use the following indentation and newlines:
template Foo with party1 : Party party2 : Party where signatory party1 observer party2 key party1 : Party maintainer party1 choice Delete : () with party : Party controller party do pure ()
-
Group all serializable interface fields into a
View
type:-- | View for `Account`. -- This data type is .. data View = View with custodian : Party -- ^ Party providing accounting -- services. id : Text -- ^ Textual description of -- the account. owner : Party -- ^ Party owning -- this account. deriving (Eq, Show)
-
Add a
viewtype
definition to the interface with theView
type:interface Account where viewtype View ...
-
Define
I
andV
type aliases for the interface and view type, respectively:type I = Account type V = View
-
In consuming code, use qualified imports
I
andV
to refer to interface and view types, -
respectively:
let iCid : ContractId Holding.I = ... let iView : Holding.V = ...
-
For interface choices with empty implemenations
To prevent us from keeping the implementation arguments 'in sync' with the choice arguments, we use
foo : Foo -> Update res choice Foo : res with a : A b : B controller actor do foo this arg
instead of
foo : A -> B -> Update res choice Foo : res with a : A b : B controller actor do foo a b
Recall that
arg
is syntactic sugar forFoo with a; b
when used in the body of the choice.
-
Place the main
do
in a choice on its own line:choice Delete : () controller party do pure ()
-
Place
do
in functions and expressions on the same line:let foo = do if a then do ... else do ...
-
Use the CamlCase naming convention for types, variables, and functions. For example:
data MyOptions = OptionOne | OptionTwo | OptionThree deriving (Eq, Ord)
mySum : Decimal -> Decimal -> Decimal mySum a b = a + b
myTerm = 3
-
Use plural 's' when naming
Set Party
.
-
Single-line body:
let a = b
-
Multi-line body:
let a = if b then c else d
-
Multiple bindings:
let a = b c = d
In case of flexible controllers, e.g.,
choice Foo : ()
with
actor : Party
bar : Int
controller actor
do
pure ()
we let the actor : Party
be the first argument of the choice.
-
Add function type signatures to all top-level functions:
add : Decimal -> Decimal -> Decimal add a b = a + b
-
Don't add type signatures for functions in
let
bindings (unless you think it is necessary):let add a b = a + b
-
Use
pure
instead ofreturn
as more idiomatic
-
Use
;
to separate parameters to differentiate from list and tuple separators:let foo = Foo with a = b; c = [d, e]; f = (g, h)
-
Use short-hand parameter notation:
let foo = Foo with a; b; c
-
Don't use
..
as it makes code harder to understand (and might cause bugs in case of code changes) -
Don't use positional constructors as they are harder to read (and might cause bugs in case of code changes)