E06120: functions can be used in generics/templates but only '?' is supported

Category: E06xxx Type hierarchy checks · Reported in phase: POST_RESOLUTION_CHECKS · Classification: FUNCTION_USED_IN_GENERIC · All error codes

What went wrong

When using function types within generics, you can only check if they're set (?), not use other operators like ==, <>, or #? on them.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 833 (Why can't I use a function type to parameterize a generic...)

Rationale

Function equality and comparison semantics are complex - functions can capture different contexts. In generic code, only the isSet (?) check is reliably meaningful and type-safe.

How to fix it

  1. Only use ? operator to check if function is set
  2. Call functions directly: result := handler(args)
  3. Do NOT compare, hash, or use other operators on functions

Common causes

  • Wanting to compare function references (not supported)
  • Trying to use == to check if same handler
  • Using functions in generic comparisons

See also

  • E06120: function operator in generic (this error)
  • E06110: function parameter in generic constructor

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E06120: functions can be used in generics/templates but only '?' is supported

#!ek9
defines module error.e06120.bad

  defines function

    validator() as abstract
      -> text as String
      <- rtn as Boolean?

    //An unconstrained generic function that adds its arguments
    combined() of type T
      ->
        first as T
        second as T
      <- rtn as T: first + second

    useWithAFunction()
      //A function has '?' and nothing else - it cannot be added
      combiner <- combined() of validator
      require combiner?

Fixed: A generic used with a function type may only ask whether a value is set ('?')

#!ek9
defines module error.e06120.good

  defines function

    validator() as abstract
      -> text as String
      <- rtn as Boolean?

    //Uses only '?' on T, so a function type can parameterise it
    firstSet() of type T
      ->
        first as T
        second as T
      <- rtn as T: first? <- first else second

    useWithAFunction()
      -> possiblyUnset as validator
      <- rtn as Boolean?
      chooser <- firstSet() of validator
      chosen <- chooser(possiblyUnset, () is validator(rtn: false))
      rtn: chosen("text")

Questions and answers

These Q&A entries show E06120 and its fix: