Modify autowrap to accept "x", "y" and "z" strings and convert them to ArgXD objects.
To reduce the verbosity when using ArgXD functions, we could consider extending the autowrap capability to include variable strings e.g. Exp2D('y') is internally is converted to Exp2D(Arg2D('y')).
This would should result in more compact, legible code.
I like this idea. The reason I didn't implement it originally with ArgXD is that Python operator precedence reduces its usefulness somewhat, compared with autowrapping constants. For example, Exp1D(5 * 3 - 2) will successfully autowrap to Exp1D(Constant1D(13.0)). However, Exp1D('x'**2 + y**2') won't autowrap to Exp1D(Arg1D('x')**2 + Arg1D('y')**2, it'll error trying to apply pow('x', 2). Similarly, Exp1D('x' + 'y') will autowrap to Exp1D('xy') and error out, probably with a confusing error message. Are you happy for the behaviour of autowrap to be slightly different between numbers and strings in this instance?
I'm only proposing accepting 'x', 'y' and 'z' as shorthand for Arg#D() (where it is the only argument), not full expressions.
It may just end up being confusing, still debating the idea in my head atm.
Another possibility would be to make some aliases. e.g. for Function3D:
X3 = Arg3D('x')
Y3 = Arg3D('y')
Z3 = Arg3D('z')
Then a user could do:
from raysect.core.math.function.float import X3 as X, Y3 as Y, Z3 as Z, Exp3D
f = Exp3D(-(X**2 + Y**2 + Z**2))
The aliases need to be named this way because just calling them X, Y, Z would mean that 1D, 2D and 3D versions would be overwritten as float/__init__.py imports all names from 1D, 2D and 3D submodules into a single namespace.
Or we could just recommend end users define these aliases themselves in their own code. That may be less fragile.