- always use the formatter
- don't use unicode, except perhaps for judoc
- avoid
Pair
- prefer enumerations with meaningful names over booleans, e.g., instead of using
Bool
define:
type Transferability := Transferable | NonTransferable;
- all imports at the beginning of the file
- explicit names for imported identifiers (
import X open using {iden1; iden2}
)- exception:
import Stdlib.Prelude open
,import Anoma open
are allowed
- exception:
- types: upper camel case (
Nat
,PublicKey
) - functions, constructors, etc: lower camel case (
tokenLogic
,transferLogic
) - instances: lower camel case with
I
at the end (instance eqNatI : Eq Nat := ..
) - boolean check functions: start with
is
(isWhatever
) - record constructors:
mk
+ type name (mkResource
) - meaningful descriptive long names for arguments of public functions, e.g.,
element
,list
,initialValue
- exception: common abbreviations allowed:
fun
,acc
- exception: common abbreviations allowed:
- short names like
x
are okay for local definitions
- put everything to the left of
:
in type signatures, with full meaningful names for arguments- temporary exception: when needed for termination, argument can be moved to the right of
:
- even when the argument type is moved to the right, give a descriptive argument name in the type:
- temporary exception: when needed for termination, argument can be moved to the right of
isMember {A} (testEq : A -> A -> Bool) (element : A) : (list : List A) -> Bool
- type variables uppercase (upper camel case, like with types)
- implicit type variables: use short version
{A}
in function signatures on the left - prefer
{A B}
over{A} {B}
in function signatures - meaningful type variable names for more "high-level" functions where this makes sense
Example:
split
{ResourceType}
{{Convertable ResourceType}}
{{HasOwner ResourceType}}
{{HasQuantity ResourceType}}
{{HasTransferability ResourceType}}
{{TransactionConvertable ResourceType ResourceType}}
(self : KeyPair)
(toSplit : ResourceType)
(quantitiesAndReceivers : List (Pair Nat PublicKey))
: Result StandardError Transaction :=
...
But we can use a short name A
in:
find {A} (predicate : A -> Bool) : (list : List A) -> Maybe A
- use
case
whenever possible; matching on multiple values handled with pairs - don't use pattern matching with side conditions when there is an
else
side condition -- convert to anif
in the body instead - don't pattern match on
Bool
-- useif
instead
- don't use "pipes" (i.e.,
|>
,<|
,>>
,<<
, etc.)- weak exception: there is a "natural" data processing pipeline in several steps
- use iterators
for
,map
, etc., instead of the function application syntax withfold
, etc. - use named application when reasonable
- the documentation string should be an English sentence
- mention the meaningful argument names in the function's judoc