Thanks Joe, but it turns out things are not so pessimistic. We tried various approaches and now have a good solution to getting an object that is appliable via ModuleApply. The behaviour of thismodule remains a mystery to us, the solution below uses a different mechanism. Our goal is really bigger than getting an appliable object, it is to have a ModuleApply with a split personality:
- Prototype object ModuleApply to act as constructor -- this is good programming style as described in Maple docs.
- Instance object ModuleApply to enable object to act as appliable operator.
So for example, suppose we want to build operators that differentiate wrt a certain variable. (Yes I know there are easier ways to do this.) We make a PDeriv object that stores a local variable x, that says what variable. We might hope to use syntax like this:
ddt := PDeriv(t);
# Now ddt should be a PDeriv object that 'differentiates wrt t'
# ddt should be appliable, so this line to return -sin(t)
Outline of how to achieve this:
- In definition of PDeriv object, have a non-static ModuleApply method that acts as a constructor
- In ModuleCopy of the PDeriv object, have code that redefines ModuleApply as a proc that acts as operator, so that instance objects are appliable.
The signature of ModuleCopy is something like
export ModuleCopy::static := proc(new::PDeriv, proto::PDeriv, otherArgs)
The redefinition of ModuleApply occurs within scope of ModuleCopy, so an object reference is available via the 'new' object that has just been made by cloning. This avoids using thismodule (which can't be used here because ModuleCopy is static). Example sheet below...
Slightly tricky programming, but very natural user interface result. Works from command line and from .mla. We have tested this approach on a couple of objects and it works great.