Why can't I constrain a Boolean type in EK9?

← Advanced Type System · Ref: Q956

Not all types can be constrained in EK9. Boolean already has exactly two values (true/false), making constraints meaningless. JSON has dynamic structure with undefined comparison semantics. Abstract types, functions, and traits cannot be instantiated as values.

NON-CONSTRAINABLE TYPES (E04010)

  Boolean — already maximally constrained (two values)
  JSON — dynamic structure, no defined comparison
  Abstract classes — cannot be instantiated
  Traits — cannot be instantiated
  Functions — not value types

CONSTRAINABLE TYPES

  String — constrain with regex or equality
  Integer — constrain with range (> 0 and < 100)
  Float — constrain with range
  Date, Time, DateTime — constrain with range
  Money — constrain with range
  Colour — constrain with specific values
  Records/Classes with comparison operators

See Q720 for constrainable types. See Q257 for constrained type overview. See Q721 for constrained types as parameters.

Example

#!ek9
defines module qa.advancedtypes.constraintinvalid

  defines type

    ValidAge as Integer constrain as
      > 0 and < 150

    ShortName as String constrain as
      matches /^[A-Za-z]{1,20}$/

  defines function

    //Opaque, so the constraint is checked at RUNTIME.
    ageFromRuntimeInput()
      <- rtn as Integer: 200

  defines program

    TypeConstraintDemo()
      stdout <- Stdout()

      if validAge <- ValidAge(25)
        stdout.println(`Valid age: ${validAge}`)

      if name <- ShortName("Alice")
        stdout.println(`Valid name: ${name}`)

      //This value is NOT statically known, so the constraint is checked at runtime and a breach
      //Panics here. Had it been knowable — a literal, a constant, or a variable carrying one —
      //it would instead be the compile error E08260, before the program ever ran.
      badAge <- ValidAge(ageFromRuntimeInput())
      stdout.println(`Bad age set: ${badAge?}`)

Common mistakes

E04010 — Boolean cannot be constrained because it already has exactly two values. Use Integer, String, or other constrainable types. See ek9 -h E04010 for details.

Incorrect:

    ValidAge as Boolean constrain as

Correct:

    ValidAge as Integer constrain as
Other ways to ask this
  • What triggers E04010 TYPE_CANNOT_BE_CONSTRAINED?
  • Which types cannot be constrained in EK9?
  • Why does constraining Boolean cause a compiler error?

Coming from another language?

Java: no built-in type constraints, use Bean Validation annotations at runtime. Python: runtime-only with pydantic. Rust: newtype pattern with constructor validation. Ada: subtype constraints on scalar types. EK9: compile-time constraint syntax with E04010 for inappropriate types.

Keywords: Boolean, E04010, JSON, abstract, constrain, constraint, invalid, range, type, value