Docs / Traits

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.