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

deprecate zero-arg Matrix constructors (#14201) #20330

Merged
merged 2 commits into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ typealias NTuple{N,T} Tuple{Vararg{T,N}}
(::Type{Array{T}}){T}(m::Int, n::Int, o::Int) = Array{T,3}(m, n, o)

(::Type{Array{T,1}}){T}() = Array{T,1}(0)
(::Type{Array{T,2}}){T}() = Array{T,2}(0, 0)

# primitive Symbol constructors
function Symbol(s::String)
Expand Down
11 changes: 11 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,17 @@ end)

@deprecate FloatRange{T}(start::T, step, len, den) Base.floatrange(T, start, step, len, den)

@noinline zero_arg_matrix_constructor(prefix::String) =
depwarn("$prefix() is deprecated, use $prefix(0, 0) instead.", :zero_arg_matrix_constructor)
function (::Type{Matrix{T}}){T}()
zero_arg_matrix_constructor("Matrix{T}")
return Matrix{T}(0, 0)
end
function (::Type{Matrix})()
zero_arg_matrix_constructor("Matrix")
return Matrix(0, 0)
end

for name in ("alnum", "alpha", "cntrl", "digit", "number", "graph",
"lower", "print", "punct", "space", "upper", "xdigit")
f = Symbol("is",name)
Expand Down
1 change: 0 additions & 1 deletion base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ include("subarray.jl")
(::Type{Vector})() = Array{Any,1}(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to deprecate Vector() as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would too but I have a suspicion it's fairly widely used, so I wanted to do the uncontroversial part first. It's fairly common to initialize a vector with zero elements and there was a period where [] created a Void eltype empty array. There's also a consistency argument here: if we deprecate that we should also deprecate Vector{T}() – are you in favor of that as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Member

@stevengj stevengj Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I grepped for Vector() or Vector{Foo}() in all registered packages, and you're right that quite a few packages use it:

ASTInterpreter,AWS,AbstractTables,ApproxFun,Bio,BlackBoxOptim,Bukdu,CBOR,Clipper,Clustering,Compat,ControlCore,ControlSystems,Cxx,DSGE,DWARF,DataCubes,DataFrames,DeterministicPolicyGradient,DifferentialDynamicProgramming,Diversity,Dopri,EMIRT,GUITestRunner,Gallium,Graft,Hecke,IntervalWavelets,Isotonic,JuliaFEM,LLVM,LightGraphs,LightGraphsExtras,Lumberjack,Mamba,MetadataTools,Metamath,MultidimensionalTables,MultipleTesting,NearestNeighbors,NetworkFlows,NullableArrays,ODBC,ODEInterface,ObjFileBase,OpenDSSDirect,ParallelAccelerator,ParserCombinator,PlotRecipes,PlyIO,Primes,QuantumLab,RData,ResettableStacks,RigidBodyDynamics,RouletteWheels,SALSA,SemidefiniteModel,SemidefiniteModels,StaticArrays,StructuredQueries,SugarBLAS,Sundials,TensorDecompositions,TerminalUI,TestRunner,ThermodynamicsTable,TimeSeries,TimeSeriesIO,TravelingSalesmanHeuristics,Turing,TypedTables,Voronoi,WiltonInts84,WordNet

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A much smaller number of packages use Matrix() or Matrix{T}():

Bio,DSGE,DifferentialDynamicProgramming,Elemental,JPLEphemeris,JuliaFEM,LightGraphs,Mamba,NearestNeighbors,OpenDSSDirect,ParallelAccelerator

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also favor deprecating Vector() and Vector{T}(), but doing so in a separate PR due to the expected controversy sounds like a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have femtocleaner would this be a less controversial change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #22717

(::Type{Vector{T}}){T}(m::Integer) = Array{T,1}(Int(m))
(::Type{Vector})(m::Integer) = Array{Any,1}(Int(m))
(::Type{Matrix})() = Array{Any,2}(0, 0)
(::Type{Matrix{T}}){T}(m::Integer, n::Integer) = Matrix{T}(Int(m), Int(n))
(::Type{Matrix})(m::Integer, n::Integer) = Matrix{Any}(Int(m), Int(n))

Expand Down
20 changes: 16 additions & 4 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,30 @@ end
@test typeof(Vector(3)) == Vector{Any}
@test typeof(Vector()) == Vector{Any}
@test typeof(Matrix{Int}(2,3)) == Matrix{Int}
@test typeof(Matrix{Int}()) == Matrix{Int}
@test typeof(Matrix(2,3)) == Matrix{Any}
@test typeof(Matrix()) == Matrix{Any}

@test size(Vector{Int}(3)) == (3,)
@test size(Vector{Int}()) == (0,)
@test size(Vector(3)) == (3,)
@test size(Vector()) == (0,)
@test size(Matrix{Int}(2,3)) == (2,3)
@test size(Matrix{Int}()) == (0,0)
@test size(Matrix(2,3)) == (2,3)
@test size(Matrix()) == (0,0)

# TODO: will throw MethodError after 0.6 deprecations are deleted
dw = Base.JLOptions().depwarn
if dw == 2
@test_throws ErrorException Matrix{Int}()
@test_throws ErrorException Matrix()
elseif dw == 1
@test_warn "deprecated" Matrix{Int}()
@test_warn "deprecated" Matrix()
elseif dw == 0
@test size(Matrix{Int}()) == (0,0)
@test size(Matrix()) == (0,0)
else
error("unexpected depwarn value")
end
@test_throws MethodError Array{Int,3}()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have a @test_deprecated macro that does this for you. Usage would be something like this:

@test_deprecated size(Matrix{Int}()) == (0,0)

which would expand to one of the following, depending on the value of Base.JLOptions().depwarn:

@test_throws ErrorException size(Matrix{Int}())
@test_warn "deprecated" size(Matrix{Int}())
@test size(Matrix{Int}()) == (0,0)

The main reason I wanted this complexity in here is so that I couldn't possibly forget to update the tests when we delete the deprecations for 1.0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a very good idea

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though we probably want to put such tests in a single place and make sure they get run regularly with all 3 values of the flag (or expand to 3 tests that modify the option in a scoped way, if that's possible inside julia)

end
@testset "get" begin
A = reshape(1:24, 3, 8)
Expand Down