-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Inconsistent eltype between map and broadcast for empty collections #20033
Comments
I've opened a PR to make Another inconsistency not covered by the PR: julia> f(x::Float64) = 1
f (generic function with 1 method)
julia> map(f, Any[])
0-element Array{Any,1}
julia> broadcast(f, Any[])
0-element Array{Int64,1}
|
Also this: julia> map((x) -> error(x), 1:0)
0-element Array{Union{},1}
julia> map((x) -> error(x), [])
0-element Array{Any,1} Looks a bit like |
Also this:
It looks like |
It's not directly julia> Core.Inference.return_type((x) -> error(), Tuple{Int})
Union{}
julia> Core.Inference.return_type((x::String) -> error(), Tuple{Int})
Union{} But the output element type is not determined with julia> foo(f, x) = f(x)
foo (generic function with 1 method)
julia> @code_warntype foo(x->error(), 1)
Variables:
#self#::#foo
f::##39#40
x::Int64
Body:
begin
return (Base.throw)((Base.ErrorException)(((Core.getfield)((Core.getfield)(Base.Main, :Base)::Any, :string)::Any)()::Any)::ErrorException)::Union{}
end::Union{}
julia> @code_warntype foo((x::String)->error(), 1)
Variables:
#self#::#foo
f::##41#42
x::Int64
Body:
begin
return (f::##41#42)(x::Int64)::Any
end::Any which is due to this. Interesting, but probably beyond the scope of this issue. |
adds a world counter and threads it everywhere and tracks all backedges add tests for some versions of #265 also updates the compile test to be world-aware and add docs for method replacement / world age note that MethodTables need to Base.serialized in a world-aware manner and MethodError needs to be world aware the age in MethodInstance is a copy of the value returned by typemap lookup since we don't currently have a mechanism for accessing that value directly plus, this seems easier anyways handle MethodInstance age range updates correctly means only updating them in-place when that doesn't potentially invalidate other consumers that might also be holding a reference to it and propagate this through the callers to type-inference virtual edges are tracked via exact signature tuple types inference is pure for backedges meaning that we only add backedges that exist at the end of inference and then add them to the correct MethodInstance object which also make codegen caching world-aware min/max validity of ml-matches results is threaded out of jl_matching_methods into inference eventually should probably switch this to use a Ref, or return the value, or something similarly more efficient than a singleton Array, but currently refpointer.jl is not part of Core.Inference incremental deserialize is aware of world counter logic by handling the follow cases: - "free-standing" methods (where age is at the default of 0), probably from a toplevel thunk or deserialize - garbage methods (really we just want to delete these, but, oh well). this is something inferred to have been replaced - applicable methods (this is the overwhelming majority of cases) the logic between TypeMapEntry, Method, and MethodInstance all agree on these concepts this uses Expr(:body) as an argument to eval to ensure that eval won't call expand, which ensures that QuoteNode works correctly and the eval is reasonably fast
@vtjnash Is there any chance this line could be changed, or should we find a workaround? |
Now consistent on current master: # Example 1
julia> h3(x::Float64...) = prod(x)
h3 (generic function with 1 method)
julia> map(h3, Int[])
0-element Array{Union{},1}
julia> broadcast(h3, Int[])
0-element Array{Union{},1}
# Example 2
julia> f(x::Float64) = 1
f (generic function with 1 method)
julia> map(f, Any[])
0-element Array{Int64,1}
julia> broadcast(f, Any[])
0-element Array{Int64,1}
# Example 3
julia> map((x) -> error(x), 1:0)
0-element Array{Union{},1}
julia> map((x) -> error(x), [])
0-element Array{Union{},1}
# Example 4
julia> map((x::String)->error(), Int[])
0-element Array{Union{},1}
julia> map(x->error(), Int[])
0-element Array{Union{},1}
|
On Julia 0.5.0:
On current master:
I guess returning
Union{}
is not intended here? Anyway, whatever element type we choose, I think we should be consistent. Cf. old discussion at #7258.The text was updated successfully, but these errors were encountered: