Zirric Styleguide
Styleguide
This guide captures the conventions used across the Zirric standard library and
proposals. Favor clarity and consistency over cleverness.
General principles
- Prefer descriptive names over abbreviations.
- Keep files small and focused.
- Match existing style in nearby modules.
Modules
Zirric favors many small modules over a few large ones. Keep each module focused
and consider hiding implementation details in an internal module.
Module names use snake_case but should avoid underscores when possible. Names
should be short, expressive, and usually plural. Keep module names aligned with
the declarations they contain.
// good
module http
module json
module strings
module reflect // reflect.typeOf
// bad
module http_client
module json_parser
module string_utils
module reflection // reflection.typeOf
If a filename or its declarations could clash with another module, declare the
module explicitly at the top of the file:
module my_module
Data types
Data type names use PascalCase. Prefer nouns, pluralize only when the type is
a collection, and avoid prefixing the module name.
Witness types describe capabilities and may be suffixed with able or ible.
// good
data Person
data People
data Printable // witness type
data Error // in module http
// bad
data person
data people
data Printer // witness type
data HttpError // in module http
Functions
Function names use camelCase. Names should read as verbs or verb phrases and
form a sentence with the module name.
// good
print
printLine
reflect.typeOf
// bad
print_line
reflect.reflectType
Variables
Variable names use camelCase. Names should be as long as their scope: short
names for tight scopes, longer names for shared or public values. Reuse common
names in well-known patterns.
// good
let name = "John"
let person = Person("John", 42)
let err = http.Error("Not found")
func printPersonName(p) {
print(p.name)
}
// bad
let n = "John"
let p = Person("John", 42)
let error = http.Error("Not found")
func printName(n) {
print(n.name)
}
Annotations
Annotations use PascalCase and should describe the property they declare.
// good
annotation Returns
annotation HasKey
annotation IsOptional
// bad
annotation Return
annotation Key
annotation Optional
Enums
Enum names use PascalCase. Choose singular nouns unless the enum itself is a
collection. For witness enums, describe the capability, optionally with a
Witness suffix.
// good
enum Stateful
enum JuristicPerson
enum FunctorWitness
// bad
enum StateOrStore
enum JuristicPersons
enum Functor
If the cases inside the enum are more relevant than the enum name itself, define
them at top level instead of nesting.
// good
enum Optional {
data Some { value }
data None
}
enum Maybe {
Optional
Any
}
// bad
enum Maybe {
enum Optional {
data Some { value }
data None
}
Any
}
Imports and layout
- Group imports together near the top of the file.
- Keep one declaration per block to make annotations and docs obvious.
- Prefer blank lines to separate logical sections.