You can get this behaviour by overloading the experimental () operator on an
object type, like so:
{. experimental .}
import math
type
Callable = object
val: int
# Make the thing callable. Needs {. experimental .}
proc `()`(c: Callable; i: int): int = c.val * i
# Make the thing exponentiable.
proc `^`(c: Callable; i: int): int = c.val ^ i
let c = Callable(val: 1)
echo c ^ 2 == 1.c ^ 2 # true!
You could probably object-ify any given function to behave this way using a macro.
