What are the naming conventions for types in EK9?
← Variable Naming Rules and Conventions · Ref: Q293
EK9 uses PascalCase for all type names: classes, records, traits, enumerations, and functions used as types. Module names use lowercase dot-separated segments.
CLASSES
PascalCase nouns describing what the class represents: CustomerOrder, PaymentProcessor, EmailValidator. Classes model entities or processors.
RECORDS
PascalCase nouns describing the data structure: Coordinate, Temperature, HttpResponse. Records are data-focused types with public fields, constructors, and operators (but no methods). Records are mutable — use 'as pure' to control mutation.
TRAITS
PascalCase adjectives or capability names: Printable, Sortable, Configurable. Traits describe what a type can do, not what it is.
ENUMERATIONS
PascalCase singular nouns: Colour, DayOfWeek, HttpStatus. Each value represents one instance of the concept.
FUNCTIONS AS TYPES
PascalCase verb phrases when used as abstract function types: FormatName, CalculateTotal, ValidateInput. Standalone functions use camelCase (see Q294).
GENERIC TYPE PARAMETERS
Single uppercase letters: T for general type, K for key, V for value, E for element. These are universally understood conventions.
MODULES
Lowercase dot-separated: com.example.banking, org.ek9.core. Module names follow reverse domain convention.
CONSTRAINED TYPES
Named for the constraint they represent: EmailAddress as String constrain, PositiveInteger as Integer constrain. The name describes what the constraint enforces.
See Q292 for variable naming. See Q294 for function naming. See Q93 for classes. See Q97 for records.
Example
defines module qa.naming.types defines trait Printable printTo() as pure abstract -> target as String <- formattedOutput as String? defines record Coordinate xPosition as Float: 0.0 yPosition as Float: 0.0 Coordinate() -> initialX as Float initialY as Float this.xPosition :=: initialX this.yPosition :=: initialY operator $ as pure <- rtn as String: `(${xPosition}, ${yPosition})` operator <=> as pure -> other as Coordinate <- rtn as Integer: xPosition <=> other.xPosition override operator ? as pure <- rtn as Boolean: xPosition? and yPosition? defines class ShapeRenderer with trait of Printable shapeName as String: String() ShapeRenderer() -> name as String this.shapeName :=: name override printTo() as pure -> target as String <- formattedOutput as String: `${shapeName} -> ${target}` operator $ as pure <- rtn as String: `Renderer(${shapeName})` override operator ? as pure <- rtn as Boolean: shapeName? defines type DayOfWeek Monday Tuesday Wednesday Thursday Friday Saturday Sunday defines function FormatCoordinate() as pure abstract -> point as Coordinate <- formattedPoint as String? defines program TypeConventionsDemo() stdout <- Stdout() // === RECORD: PascalCase noun === origin <- Coordinate(0.0, 0.0) destination <- Coordinate(3.5, 7.2) stdout.println(`Origin: ${origin}`) stdout.println(`Destination: ${destination}`) // === CLASS WITH TRAIT: PascalCase === renderer <- ShapeRenderer("Circle") renderedOutput <- renderer.printTo("Canvas") stdout.println(renderedOutput) // === ENUMERATION: PascalCase singular === today <- DayOfWeek.Wednesday stdout.println(`Today: ${today}`) // === GENERIC TYPE PARAMETER CONVENTION === names <- ["Alice", "Bob", "Charlie"] for n in names stdout.println(`Name: ${n}`) // === FUNCTION TYPE: PascalCase verb phrase === formatter <- (capturedOrigin: origin) is FormatCoordinate as pure function formattedPoint :=? `Point at ${point} from ${capturedOrigin}` stdout.println(formatter(destination))
Common mistakes
E50060 — The method is named 'printTo' not 'render'. Calling a method that does not exist on the type produces a resolution error. See ek9 -h E50060 for details.
Incorrect:
renderedOutput <- renderer.render("Canvas")
Correct:
renderedOutput <- renderer.printTo("Canvas")
E08090 — If the variable 'today' is declared but never referenced in any expression, the compiler rejects it as unused. See ek9 -h E50050 for details.
Incorrect:
todaySummary <- `Today: ${today}`
Correct:
stdout.println(`Today: ${today}`)
Other ways to ask this
- How should I name classes, records, and traits in EK9?
- What naming style do EK9 types use?
- How do I name modules and generic type parameters in EK9?
Coming from another language?
Java: PascalCase for classes (convention, not enforced), package names lowercase. Python: PascalCase for classes (PEP 8, not enforced), snake_case for modules. Rust: PascalCase for types (enforced as warning), snake_case for modules. Go: PascalCase for exported types, lowercase for unexported. C++: no standard, varies widely. Kotlin: PascalCase for classes (convention), package names lowercase. Swift: PascalCase for types (convention). EK9: PascalCase for all types, lowercase dot-separated for modules, single uppercase for generics, descriptive naming enforced by compiler.
Keywords: type, record, function, module, generic, naming, PascalCase, class, convention, constrained, enumeration, trait, identifier