Definitely doesn't work that way. If I check both orderings the code to fix (5) works.
You might be thinking of promote, not promote_rule. That's not a useful function though because it tries to convert values to a given type, which is basically useless for things like a conversion to integers_mod_n where it would need to know n in order to do this. It can't know that just from the type, however. This assumption that you can always construct a value of a given type just from the type information is littered throughout Julia. It causes a lot of problems for us. For example, the matrix code in Julia everywhere wants to be able to do zero(T) where T is some type. But again, you can't construct the zero object of integers modulo n without knowing n, and you certainly don't want n in the type (or the compiler will dispatch on n, which would make multimodular algorithms takes hours instead of a second as everything was recompiled over and over for every modulus n you used). The matrix code should be using zero(v) where v is a value of type T. You can always construct one value of a given type from another value of that type. I don't know a solution for the convert problem. Probably it has to be the same, i.e. you need to convert one value to the type of another value. I'm sure no one is going to like that solution, but I don't see any other way around it. Bill. On 22 March 2016 at 23:39, Jeffrey Sarnoff <jeffrey.sarn...@gmail.com> wrote: > That is not supposed to be how it works! > As I recall there was a meetup where JeffB explains that promote_rule > always never cares about the order of its arguments and internals generate > lookups for both orderings. > > > On Tuesday, March 22, 2016 at 6:26:51 PM UTC-4, Bill Hart wrote: >> >> OK I solved (5). Apparently promote_rule needs to be defined for both >> orderings of its arguments if one wants it to work with arguments in either >> order. >> >> I can't think of any reason why one wouldn't expect a promote_rule to >> come up with a common type to which both can be promoted, regardless of the >> order of its arguments. But maybe such an application exists. So maybe this >> is actually reasonable behaviour. >> >> Bill. >> >> On Tuesday, 22 March 2016 22:58:29 UTC+1, Bill Hart wrote: >>> >>> Another problem: >>> >>> 5) We have been using promote_type to find out the type returned by a >>> promote_rule we defined, which has mostly worked fine, oddly enough. But >>> now that I realise that's not what promote_type is for, I switched to using >>> promote_rule instead, since it just returns Union{} if there is no >>> promote_rule for the supplied types. But this doesn't work in Nemo. >>> >>> Even though we have an explicit promote rule (not generated at runtime) >>> >>> Base.promote_rule{T <: Integer}(::Type{fmpz_poly}, ::Type{T}) = fmpz_poly >>> >>> a call to Base.promote_rule(fmpz_poly, Int) inside Nemo returns Union{}. >>> >>> However, such a call from the REPL results in Nemo.fmpz_poly. >>> >>> There's clearly something broken here. I need to be able to explicitly >>> tell if the promote_rules that I create actually exist or not. At present I >>> only seem to be able to do that from the REPL, not inside my actual module. >>> >>> Bill. >>> >>