Are these really problems, though?
(I assume you mean one(x)
, since normally x^0 == one(x)
.)
The function can use one(x)
in its definition, and if one
is not defined for some type, then it will simply throw an error that says one
is not defined, so then you can either define a one
, or if the type there is no sensible one
, you shouldn’t be calling x^0
anyway.
The same can be said for p < 0
and inv(x)
.
for p==1
, we can just return copy(x)
, no? This is what is in the current definition of power_by_squaring
anyway.
I think this is the real issue. Maybe for ^
this modular approach of
- Defining only base methods like
+,-,*,inv,zero,one
etc. for types
- General advanced functions like
exp, sin, ^, abs
etc. use combinations of base and advanced functions.
- Which advanced functions can be used with which arguments depend on which base methods were defined.
works fine, but for types where the internal structure completely changes how one accesses data inside x
for multiple ‘advanced’ functions, this approach doesn’t really make sense.
I just learnt about this from the posts by @Tamas_Papp and @tkluck, but apparently the way to deal with this is either through strict type hierarchies or interfaces, though I have trouble coming up with examples myself…maybe something to do with an Iterator
that IsInfinite()
?
Interfaces aside, I am still convinced that having the current ^(x::Number, p::Integer)
be for x::All
instead would make sense, but it was decided by @iamed2 (and everyone who let the PR through) that regardless of the questionable generality, there is an issue with method ambiguity. I will accede that the usability gained by removing the method ambiguity is better than the generality lost.
Thanks to everyone who contributed to the discussion so far
I now have a better framework for thinking and learning about these issues—and a better idea of how Julia developers think about them. Hopefully others also found some enlightenment here.