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

Typing of array operations #6173

Closed
timholy opened this issue Mar 14, 2014 · 6 comments
Closed

Typing of array operations #6173

timholy opened this issue Mar 14, 2014 · 6 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@timholy
Copy link
Member

timholy commented Mar 14, 2014

Illustrated with SIUnits, although this issue is not specific to that case:

julia> using SIUnits

julia> a = [1Meter, 2Meter]
2-element Array{SIQuantity{Int64,1,0,0,0,0,0,0},1}:
 1 m 
 2 m 

julia> l = 0.5Meter
0.5 m 

julia> r = l./a
2-element Array{SIQuantity{Float64,m,kg,s,A,K,mol,cd},1}:
  0.5 
 0.25 

julia> r[1]
0.5 

julia> typeof(r[1])
SIQuantity{Float64,0,0,0,0,0,0,0} (constructor with 1 method)

julia> typeof(l./a[1])
Float64

Fixing this seems a little delicate. For the functions here, I tested a solution that allocates the output in the following manner:

F = Array(typeof(($f)((isempty(A) ? one(S) : A[1])::S, (isempty(B) ? one(B) : B[1])::T)),
                      promote_shape(size(A),size(B)))

To try to avoid problems from when one(T) isn't defined, it uses the first element of the array and only falls back to one(T) if the array is empty. That still leaves the possibility for error (and is therefore far from ideal), but it narrows the frequency with which it should happen.

While this fixes this particular example, unfortunately it causes trouble for some of the bitarray tests:

    JULIA test/bitarray
     * bitarray
exception on 1: ERROR: no method convert(Type{Array{Bool,1}}, Int64)
 in & at array.jl:763
 in check_bitop at bitarray.jl:8
 in runtests at /home/tim/src/julia/test/testdefs.jl:5
 in anonymous at multi.jl:629
 in run_work_thunk at multi.jl:590
 in remotecall_fetch at multi.jl:663
 in remotecall_fetch at multi.jl:678
 in anonymous at task.jl:1309
while loading bitarray.jl, in expression starting on line 552
ERROR: no method convert(Type{Array{Bool,1}}, Int64)
 in & at array.jl:763
 in check_bitop at bitarray.jl:8
 in runtests at /home/tim/src/julia/test/testdefs.jl:5
 in anonymous at multi.jl:629
 in run_work_thunk at multi.jl:590
 in remotecall_fetch at multi.jl:663
 in remotecall_fetch at multi.jl:678
 in anonymous at task.jl:1309
while loading bitarray.jl, in expression starting on line 552
while loading /home/tim/src/julia/test/runtests.jl, in expression starting on line 34

make[1]: *** [bitarray] Error 1
make: *** [test-bitarray] Error 2

Not sure what folks think would be the right way forward here. I don't really see an ideal solution.

@andreasnoack
Copy link
Member

I ended up doing something very similar for the LU and QR but hadn't seen the deep problem of non-existence of one for arrays types before the discussion in JuliaLang/LinearAlgebra.jl#94

@toivoh
Copy link
Contributor

toivoh commented Mar 15, 2014

The trouble with using the first element is that it can give unexpected
results for loosely typed arrays.

@timholy
Copy link
Member Author

timholy commented Mar 15, 2014

Hmm, an excellent point. Here's a fun one:

julia> a = Any[1Meter, 2Meter]
2-element Array{Any,1}:
 1 m 
 2 m 

julia> l = 0.5Meter
0.5 m 

julia> l./a
ERROR: type: SIQuantity: in T, expected T<:Number, got Type{Any}
 in ./ at array.jl:793

@andreasnoack
Copy link
Member

but the result of one(Real) or any other abstract type is also difficult to predict.

@timholy
Copy link
Member Author

timholy commented Mar 15, 2014

I should have clarified that this result is with current master, because of:

julia> Base.promote_array_type(typeof(l), eltype(a))
ERROR: type: SIQuantity: in T, expected T<:Number, got Type{Any}
 in promote_array_type at array.jl:730

This is ultimately a consequence of

T = typeof(l)
S = Any
julia> Base.promote_rule(S,T)
ERROR: type: SIQuantity: in T, expected T<:Number, got Type{Any}
 in promote_rule at /home/tim/.julia/v0.3/SIUnits/src/SIUnits.jl:95

Presumably this could be fixed to return Any.

However, note another hazard with the one(T) solution:

julia> one(Any)
1

@kshyatt kshyatt added the types and dispatch Types, subtyping and method dispatch label Sep 15, 2016
@JeffBezanson
Copy link
Member

I think this is now fixed by our broadcast machinery?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

6 participants