Traits
Traits declare required methods and may provide default implementations. Implementing types pull in the defaults for free, and can override individual methods where they want different behavior.
Declaring a trait
shape-trait.kex
trait Shape do
area : () -> Float
perimeter : () -> Float
# default implementation, written against `this`
let describe = "area=${this.area}, perimeter=${this.perimeter}"
end Implementing with make
shape-impl.kex
record Circle do
radius : Float
end
make Circle, implement: Shape do
let area = Math.PI * @radius * @radius
let perimeter = 2.0 * Math.PI * @radius
end
record Rectangle do
width : Float
height : Float
end
make Rectangle, implement: Shape do
let area = @width * @height
let perimeter = 2.0 * (@width + @height)
let describe = "Rectangle ${@width}x${@height} (area=${this.area})" # override
end Trait-constrained functions
Function parameters can be constrained to a trait, so you can call any of its methods on the value.
trait-constraint.kex
foul printShape(s: Shape) do
IO.printLine(s.describe)
end
shapes.each(&printShape) Built-in traits
Comparable and Equatable ship with the standard
library and provide derived methods like lessThan? /
equalTo? from a single compare.