Chapter 18: a sealed family, built

Chapter 18 ends by sealing a family: Payment may be implemented by Card and Cash and by nothing else. The IDE builds the trait, the two classes and the sealing; what is typed is the logic no tool can write. Sealing lists types that already exist, so it comes after them. To play it in the IDE: Help > Lessons > Getting Started with EK9…, or ek9 -ide -lesson book-allow-only.

The EK9 IDE as the lesson opens

What you'll build

The lesson builds this program from a file holding only its module line - the finished file, as the book prints it.

#!ek9
defines module book.allow

  defines trait
    Payment allow only Card, Cash
      amount() as pure
        <- rtn as Integer?

  defines class
    Card with trait of Payment
      override amount() as pure
        <- rtn as Integer: 100
      default operator ?

    Cash with trait of Payment
      override amount() as pure
        <- rtn as Integer: 50
      default operator ?

  defines program
    Show()
      stdout <- Stdout()
      p as Payment: Card()
      stdout.println(`amount ${p.amount()}`)

Step 1: A trait, and its abstract method

Choose Code > New Construct > Trait…

The EK9 IDE once this is done: Choose Code > New Construct > Trait…

Payment is the trait's name. Type Payment and choose Preview.

The EK9 IDE just before choosing Preview: Payment is the trait's name

The preview shows Payment about to be written. Choose Apply.

The EK9 IDE just before choosing Apply: The preview shows Payment about to be written

Right-click the Payment line and choose Add Method…

The EK9 IDE once this is done: Right-click the Payment line and choose Add Method…

amount is the method's name, Integer the return type, pure ticked. Fill them in and choose Apply.

The EK9 IDE just before choosing Apply: amount is the method's name, Integer the return type, pure ticked

Select the stub, from <- rtn as Integer: 0 down to its //AI line, and type <- rtn as Integer? - no value: that is what makes amount abstract. Saves when typed.

The EK9 IDE once this is done: Select the stub, from <- rtn as Integer

Step 2: Card

Choose Code > New Construct > Class…

The EK9 IDE once this is done: Choose Code > New Construct > Class…

Card is the class's name. Type Card and choose Preview.

The EK9 IDE just before choosing Preview: Card is the class's name

The preview shows Card about to be written. Choose Apply.

The EK9 IDE just before choosing Apply: The preview shows Card about to be written

Right-click the Card line and choose Adopt Trait…

The EK9 IDE once this is done: Right-click the Card line and choose Adopt Trait…

Type Payment as the trait - Implement method stubs is already chosen - and choose OK.

The EK9 IDE just before choosing OK: Type Payment as the trait - Implement method stubs is already chosen - and choose OK

Adopt Trait changes the open file in the editor, not yet saved. Choose File > Save.

The EK9 IDE once this is done: Adopt Trait changes the open file in the editor, not yet saved

Select amount's stub, from <- rtn as Integer: 0 down to its //AI line, and type <- rtn as Integer: 100. Saves when typed.

The EK9 IDE once this is done: Select amount's stub, from <- rtn as Integer

Right-click the Card line and choose Add Operator ▸ ? (isSet) ▸ default - Card has no field to make one for it.

The EK9 IDE once this is done: Right-click the Card line and choose Add Operator ▸ ? (isSet) ▸ default - Card has no field to make one for it

Step 3: Cash

Choose Code > New Construct > Class…

The EK9 IDE once this is done: Choose Code > New Construct > Class…

Cash is the class's name. Type Cash and choose Preview.

The EK9 IDE just before choosing Preview: Cash is the class's name

The preview shows Cash about to be written. Choose Apply.

The EK9 IDE just before choosing Apply: The preview shows Cash about to be written

Right-click the Cash line and choose Adopt Trait…

The EK9 IDE once this is done: Right-click the Cash line and choose Adopt Trait…

Payment again, stubs implemented. Choose OK.

The EK9 IDE just before choosing OK: Payment again, stubs implemented

Choose File > Save.

The EK9 IDE once this is done: Choose File > Save

Select amount's stub and type <- rtn as Integer: 50. Saves when typed.

The EK9 IDE once this is done: Select amount's stub and type <- rtn as Integer

Right-click the Cash line and choose Add Operator ▸ ? (isSet) ▸ default.

The EK9 IDE once this is done: Right-click the Cash line and choose Add Operator ▸ ? (isSet) ▸ default

Step 4: Sealing the family

Right-click the Payment line and choose Change Modifier > Seal Type…

The EK9 IDE once this is done: Right-click the Payment line and choose Change Modifier > Seal Type…

Card and Cash are already ticked - every existing implementor must stay listed. Choose Preview.

The preview shows Payment gaining allow only Card, Cash. Choose Apply.

The EK9 IDE just before choosing Apply: The preview shows Payment gaining allow only Card, Cash

Step 5: The program

Choose Code > New Construct > Program…

The EK9 IDE once this is done: Choose Code > New Construct > Program…

Show is the program's name. Type Show and choose Preview.

The EK9 IDE just before choosing Preview: Show is the program's name

The preview shows Show about to be written. Choose Apply.

The EK9 IDE just before choosing Apply: The preview shows Show about to be written

Select the stub, from ready <- true down to its //AI line, and type Show's body: a Payment held as a Card, and its amount printed. Saves when typed.

The EK9 IDE once this is done: Select the stub, from ready <- true down to its //AI line, and type Show's body

Step 6: Run it

Choose Run > Run Program…

The EK9 IDE once this is done: Choose Run > Run Program…

The project's only program is already chosen. Choose Run.

amount 100 - the Payment is a Card, and only a Card or a Cash can ever be one. Choose Close.

The EK9 IDE just before choosing Close: amount 100 - the Payment is a Card, and only a Card or a Cash can ever be one

The result

AllowOnly.ek9 now reads exactly as chapter 18 of Getting Started with EK9 shows it: Payment is a closed family - exactly Card and Cash - and the compiler will refuse a third. Seal Type had to come last, because it lists types that must already exist; Unseal Type and Add to Allowlist… sit beside it in the same Change Modifier menu. AI assistants use ek9_new_construct, ek9_add_method, ek9_adopt_trait, ek9_add_operator, ek9_seal_type and ek9_add_program.

The EK9 IDE when the lesson has finished

Where this lesson comes from