How do function hierarchies compare to class hierarchies?
← Function Extension · Ref: Q591
Both function hierarchies and class hierarchies provide polymorphism in EK9, but they serve different purposes. Functions are best for stateless transformations; classes are best for stateful entities.
FUNCTION HIERARCHIES
Abstract function defines a callable contract. Concrete functions implement it. No state (unless using closure capture). Best for: transformations, strategies, pipelines, predicates.
CLASS HIERARCHIES
Abstract class defines entity with state and behavior. Concrete classes extend it. Full state management with fields and methods. Best for: domain entities, stateful components, complex objects.
WHEN TO USE FUNCTIONS
Single input-output transformations. Strategy pattern with no shared state. Stream pipeline stages (filter, map, etc.). Predicates and validators.
WHEN TO USE CLASSES
Domain objects with multiple fields. Objects with multiple methods. Stateful services and components. Complex object graphs.
KEY DIFFERENCES
Functions cannot hold mutable state (closures capture values, not variables). Classes can have fields, methods, and operators. Functions are more concise for simple transformations. Classes provide richer abstractions.
See Q588 for function extension. See Q103 for abstract classes. See Q212 for composition over inheritance. See Q214 for strategy pattern.
Example
defines module qa.function.vsclass defines constant MIN_VALIDATION_LENGTH <- 2 defines function //Function hierarchy: stateless transformation Validator as pure abstract -> input as String <- isValid as Boolean? LengthValidator is Validator as pure -> input as String <- isValid as Boolean: length input > MIN_VALIDATION_LENGTH PatternValidator is Validator as pure -> input as String <- isValid as Boolean: input contains "@" defines class //Class hierarchy: stateful entity Document as abstract title <- String() Document() -> title as String this.title: title title() as pure <- rtn as String: title wordCount() as pure abstract <- rtn as Integer? default operator ? TextDocument extends Document content <- String() TextDocument() -> title as String content as String super(title) this.content: content override wordCount() as pure <- rtn as Integer: length content default operator ? defines program FunctionVsClassHierarchyDemo() stdout <- Stdout() //Function hierarchy: simple validation validators <- List() of Validator validators += LengthValidator validators += PatternValidator testInput <- "a@b" for validator in validators stdout.println(`Valid: ${validator(testInput)}`) //Class hierarchy: rich entity doc <- TextDocument("Report", "This is the content of the report") stdout.println(`${doc.title()}: ${doc.wordCount()} chars`)
Common mistakes
E05050 — The super() call must be the very first statement in a child class constructor. No code can execute before the parent is initialized. See ek9 -h E05050 for details.
Incorrect:
TextDocument()
->
title as String
content as String
this.content: content
super(title)
Correct:
TextDocument()
->
title as String
content as String
super(title)
this.content: content
E05120 — When overriding an abstract method from a parent class, the 'override' keyword is required. Omitting it triggers a missing override error. See ek9 -h E05120 for details.
Incorrect:
wordCount() as pure <- rtn as Integer: length content
Correct:
override wordCount() as pure <- rtn as Integer: length content
Other ways to ask this
- Should I use function extension or class inheritance?
- What is the difference between function and class hierarchies?
- When should I prefer functions over classes for polymorphism?
Coming from another language?
Java: interfaces for behavior, classes for state. Python: first-class functions but no type hierarchy. Rust: Fn traits for functions, structs for state. Go: interfaces for behavior, structs for state. EK9: both functions and classes are nominal types with inheritance hierarchies.
Keywords: stateless, function, polymorphism, comparison, visitor, extend, class, when, abstract, handler, sealed, state, hierarchy