// Reification of an operator in a type-safe language // -has a name // -has 0 or more arguments // -each argument has a type and can have a name (otherwise it gets some default name like "argument 1") // -has an optional return type (or return type null for no return value) // -to return multiple values, use a struct type // T is the meta-type for argument and return types persistable sclass GOperator { gettable S name; gettable L arguments; gettable T returnType; record noeq Argument(int index, S name, T type) {} *(S *name) {} // add argument selfType arg(S name default makeDefaultArgumentName(), T type) { arguments = createOrAdd(arguments, new Argument(l(arguments), name, type)); this; } selfType returns(T type) { returnType = type; this; } S makeDefaultArgumentName() { ret "arg" + (l(arguments)+1); } }