Create me an abstract transformer function that a dynamic function instance can extend — showing that 'as abstract' on a function makes it implicitly open.

← Functions and Methods · Ref: Q1253

An ABSTRACT function in EK9 is IMPLICITLY open — just like an abstract class. You do NOT need to write 'as open' alongside 'as abstract' because an abstract function has no body and is useless without a concrete dynamic instance.

ABSTRACT FUNCTION

  transformer() as pure abstract
    -> input as String
    <- rtn as String?

An abstract function has a signature (parameters and return type) but NO body. It cannot be called directly — only through a dynamic instance that provides the body.

DYNAMIC INSTANCE PROVIDING THE BODY

  trimAndUppercase <- () is transformer as pure function
    rtn: input.trim().upperCase()

The '() is transformer as pure function' creates a dynamic instance that supplies the missing body. The 'input' parameter and 'rtn' return variable come from the abstract function's signature.

TWO WAYS TO MAKE A FUNCTION EXTENSIBLE

- 'as open' — concrete function with default body, dynamic instances are optional (Q1252)
- 'as abstract' — signature only, dynamic instances are REQUIRED

Abstract functions are typically used as STRATEGY interfaces — different dynamic instances are chosen at runtime (see Q1238 for the strategy pattern).

USAGE

  result <- trimAndUppercase("  hello ek9  ")
  stdout.println(result)
  // Output: HELLO EK9

See Q1252 for 'as open' functions. See Q1238 for strategy pattern using abstract functions. See Q1043 for E05030 diagnosis.

Example

#!ek9
defines module qa.functionsandmethods.abstracttransformer

  defines function

    transformer() as pure abstract
      -> input as String
      <- rtn as String?

  defines program

    AbstractTransformerDemo()
      stdout <- Stdout()

      trimAndUppercase <- () is transformer as pure function
        rtn: input.trim().upperCase()

      result <- trimAndUppercase("  hello ek9  ")
      stdout.println(result)

Common mistakes

E07110 — A function with no body must be 'as abstract'. 'as open' is for functions WITH a default body that can be overridden. See ek9 -h E07110 for details.

Incorrect:

transformer() as pure open
      -> input as String
      <- rtn as String?

Correct:

transformer() as pure abstract
      -> input as String
      <- rtn as String?
Other ways to ask this
  • Does an abstract function need 'as open' in EK9?
  • Show me that an abstract function is implicitly extensible by dynamic instances.
  • Write an abstract transformer and a dynamic function that implements it.
  • How does 'as abstract' remove the need for 'as open' on a function?

Coming from another language?

Java: abstract methods on interfaces, lambdas implement the interface. Kotlin: abstract fun + lambda. Scala: abstract def + anonymous function. Rust: trait method without default. Python: abstractmethod decorator. EK9: 'as abstract' on a standalone function, dynamic instances supply the body.

Keywords: abstract function, as abstract, dynamic instance, function, implicitly open, transformer