Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promotion of four quantities fails #119

Closed
mlhetland opened this issue Feb 6, 2018 · 4 comments
Closed

Promotion of four quantities fails #119

mlhetland opened this issue Feb 6, 2018 · 4 comments

Comments

@mlhetland
Copy link

For example:

julia> promote(1cm, 1.0kg, 1s, 1N)
ERROR: MethodError: Cannot `convert` an object of type Tuple{Unitful.Quantity{…}} …

Promoting three or fewer quantities works just fine (as does promoting four or more other Julia values in general, of course).

@ajkeller34
Copy link
Collaborator

Interesting, this is automatically fixed in julia 0.7 and related to changes to dispatch. See JuliaLang/julia#21026 and JuliaLang/julia#23017. I'll keep this open until julia 0.7 is released but I'm not really sure what I can do about it until then. If you're in a jam, you could try defining:

Base.convert(::Type{Tuple{Vararg{Quantity{T}}}}, x::Tuple) where {T} = Base.cnvt_all(Quantity{T}, x...)

which should fix your problems, but may count as type piracy and is perhaps frowned upon.

@mlhetland
Copy link
Author

Thanks! If it works in 0.7, that's good enough for me. For now, I just hacked a manual solution.

@ajkeller34
Copy link
Collaborator

Since Unitful's master branch only supports Julia 0.7, the only thing left to do is tag a release soon. I'm going to mark this as closed.

@singularitti
Copy link
Contributor

singularitti commented Oct 18, 2019

Is this really fixed? I still have the same problem on Unitful.jl v0.17.0 on Julia 1.2.0.

julia> promote(1u"cm", 1.0u"kg", 1u"s", 1u"N")
ERROR: MethodError: Cannot `convert` an object of type Tuple{Quantity{Int64,𝐓,Unitful.FreeUnits{(s,),𝐓,nothing}},Quantity{Int64,𝐋*𝐌*𝐓^-2,Unitful.FreeUnits{(N,),𝐋*𝐌*𝐓^-2,nothing}}} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

I have several other tests:

using Unitful

a = 1u"m"
b = 2.0u"eV"
c = 3.0u"J"
d = 1
e = 1.0
f = 2.0u"m"

julia> promote(a, b, c, f)
(1.0 m, 2.0 eV, 3.0 J, 2.0 m)

julia> promote(a, 1, 2.0)
(1.0 m, 1.0, 2.0)

julia> promote(1, c, b)
(1.0, 3.0 J, 2.0 eV)

julia> promote(1, c, b, d)
ERROR: MethodError: Cannot `convert` an object of type Tuple{Quantity{Float64,𝐋^2*𝐌*𝐓^-2,Unitful.FreeUnits{(eV,),𝐋^2*𝐌*𝐓^-2,nothing}},Int64} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

julia> promote(1, c, b, a)
ERROR: MethodError: Cannot `convert` an object of type Tuple{Quantity{Float64,𝐋^2*𝐌*𝐓^-2,Unitful.FreeUnits{(eV,),𝐋^2*𝐌*𝐓^-2,nothing}},Quantity{Int64,𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}}} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

julia> promote(1, c, b, f)
(1.0, 3.0 J, 2.0 eV, 2.0 m)

julia> promote(1, c, b, e)
ERROR: MethodError: Cannot `convert` an object of type Tuple{Quantity{Float64,𝐋^2*𝐌*𝐓^-2,Unitful.FreeUnits{(eV,),𝐋^2*𝐌*𝐓^-2,nothing}},Float64} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

I found the problem was due to this line:

function _promote(x, y, zs...)
    @_inline_meta
    R = promote_typeof(x, y, zs...)
    return (convert(R, x), convert(R, y), convert(Tuple{Vararg{R}}, zs)...)
end

The last line uses a convert on zs. And those errors:

julia> convert(Tuple{Vararg{Quantity{Float64}}}, (1, 2))
ERROR: MethodError: Cannot `convert` an object of type Tuple{Int64,Int64} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

julia> convert(Tuple{Vararg{Quantity{Float64}}}, (1.0, 2.0))
ERROR: MethodError: Cannot `convert` an object of type Tuple{Float64,Float64} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

julia> convert(Tuple{Vararg{Quantity{Float64}}}, (1u"m", 2.0u"kg"))
ERROR: MethodError: Cannot `convert` an object of type Tuple{Quantity{Int64,𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}},Quantity{Float64,𝐌,Unitful.FreeUnits{(kg,),𝐌,nothing}}} to an object of type Tuple{Vararg{Quantity{Float64,D,U} where U where D,N} where N}

cause the above problems.

Is it a bug or we should not promote values like the above examples?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants