Can I name my own class, record, enumeration or function after a built-in type such as Colour, Money or Date?

← Variable Naming Rules and Conventions · Ref: Q1389

No. No construct of any kind - class, record, trait, component, function, enumeration or other type, text, service, application, program or constant - may take the name of a built-in construct. The compiler rejects it with E01090.

WHY

The built-in module org.ek9.lang is visible in every source file without being imported. A user class called Date would give 'Date' two meanings in one program: which one a line means would depend on where you are reading. That confuses a person, and it confuses an AI generating or reviewing code even more. EK9 removes the second meaning instead of asking you to keep track of it.

HOW IT IS CHECKED

No list of names is involved. Before a construct is defined, the compiler resolves its name; if that finds a built-in construct, E01090 is reported. Every current and future built-in is covered.

WHAT TO DO

Choose a name that says what YOUR construct is: an enumeration of colours becomes Hue (or TrafficLight, Paint...), a record of money becomes Amount or Price, your own Date becomes AppointmentDate. The built-in types remain available and unambiguous alongside yours - this program uses the built-in Money literal next to its own Amount.

Variables are not affected: a variable called colour is fine. See also E01091 (type parameter names) and E01089 (names differing only by case).

Example

defines module qa.naming.builtinnames

  defines type

    Hue
      Red
      Green
      Blue

  defines class

    Amount
      pence <- Integer()
      code <- String()

      Amount()
        ->
          pence as Integer
          code as String
        this.pence: pence
        this.code: code

      describe()
        <- rtn as String: `${pence} ${code}`

      default operator

  defines program

    BuiltInNamesDemo()
      stdout <- Stdout()

      shade <- Hue.Green
      stdout.println(`Hue: ${shade}`)

      price <- Amount(250, "GBP")
      stdout.println(`Amount: ${price.describe()}`)

      //The built-in Money is still there, alongside our own Amount - and unambiguous
      paid <- 2.50#GBP
      stdout.println(`Money: ${paid}`)

Common mistakes

E01090 — Colour is a built-in type (the #RRGGBB colour literal type). Name the enumeration for what it is. See ek9 -h E01090.

Incorrect:

    Colour
      Red
      Green
      Blue

Correct:

    Hue
      Red
      Green
      Blue

E01090 — Money is a built-in type. Your own money-like construct needs its own name, e.g. Amount or Price. See ek9 -h E01090.

Incorrect:

    Money
      pence <- Integer()

Correct:

    Amount
      pence <- Integer()

E01090 — Programs, functions and constants are constructs too - Stdout is the built-in standard output type. See ek9 -h E01090.

Incorrect:

    Stdout()

Correct:

    BuiltInNamesDemo()
Other ways to ask this
  • What is E01090 in EK9?
  • Why does EK9 reject a class called Date?
  • Why can't I define an enumeration called Colour in EK9?
  • What does 'is the name of a built-in construct' mean?

Coming from another language?

Java: a class named Date in your package silently shadows java.util.Date for unqualified use in that package, and which one an unqualified 'Date' means depends on the imports. Python: assigning 'list = ...' or defining 'class str' shadows the builtin in that scope. C#/Kotlin: a user type can hide a framework type of the same name. EK9: built-in names are reserved for the built-ins - one name, one meaning.

Keywords: Money, shadow, Date, construct, conflict, name, naming, E01090, Colour, built-in