fix non numeric accumulate(op, v0, x) (#25506)#25515
fix non numeric accumulate(op, v0, x) (#25506)#25515jw3126 wants to merge 5 commits intoJuliaLang:masterfrom
Conversation
|
@simonbyrne You said in the issue #25506:
Can you explain whats wrong with the fix in this PR and provide an example that fails? |
|
I don't think this will fix |
|
@simonbyrne I think the
|
|
Can somebody review this? |
I would like to change that to be consistent |
|
Its was a conscious design decision, that |
|
I'm actually trying to find that discussion at the moment: do you have a link? I would like to change |
|
FWIW I am also in favor of making this consistent with |
|
Thanks for the links, I'll leave that to a separate issue. Even if we don't widen, I would still prefer to use |
base/multidimensional.jl
Outdated
|
|
||
| function accumulate_pairwise(op, v::AbstractVector{T}) where T | ||
| out = similar(v, rcum_promote_type(op, T)) | ||
| out = similar(v, promote_op(op, T)) |
There was a problem hiding this comment.
This (and others) should probably be promote_op(op, T, T): though built-in operators provide unary versions, anonymous functions typically won't.
There was a problem hiding this comment.
Oh thanks! I somehow assumed promote_op(op,T) = promote_op(op,T,T) without checking. Documenting it is a good idea!
|
Can someone rerun CI? |
|
The correct thing to do would be to do the same as |
|
@martinholters What do you mean by empty case? Are you talking about |
The situation where the output is empty, so where
Conceptually, it works as follows:
If the code is type stable, inference can figure out that the type check in 2) can be optimized away. So a sufficiently tweaked implementation can be quite efficient. However, julia> accumulate(*, ['a', 'b'])
2-element Array{Any,1}:
'a'
"ab"may not be what you want in the end. (But then again, |
|
To save you some time hunting around (the broadcast code is a bit confusing): |
|
Mhhh, seeing julia> accumulate(*, ['a', 'b'])
2-element Array{Any,1}:
'a'
"ab"hurts my eyes. Getting |
|
I think we should still be able to use |
|
@simonbyrne okay you are right, we could still use |
Maybe we have different opinions of what "right" is here? To me, julia> accumulate(*, [1m, 1m]) # using Unitful (result faked)
2-element Array{Unitful.Quantity{Int64,D,U} where U where D,1}:
1 m
1 m^2which is basically the same situation. Would we want to enforce some other element type (and likely cause a failure by doing so)? |
|
To me the difference between Base.promote_rule(::Type{Char}, ::Type{S}) where S<:AbstractString = S
Base.convert(::Type{String}, c::Char) = string(c)allowing this to work: julia> promote('a', "ab")
("a", "ab")That would, I believe, naturally make the |
|
Okay maybe the issue is indeed more with general |
|
Ultimately the reason you want |
|
@jekbradbury There isn't always such an identity element, e.g. |
|
Given that |
|
I agree, which is why I defined a |
|
Assuming #25728 lands, could this serve as a prototype implementation? function accumulate(f, x)
res = Vector{Any}(uninitialized, length(x))
res[1] = x[1]
for i in 2:length(x)
res[i] = f(res[i-1], x[i])
end
restype = mapreduce(typeof, promote_type, res)
return convert(Vector{restype}, res)
endObviously, this is not the most efficient way to go about it and is restricted to non-empty |
|
I've created a WIP fix in #25766, which I think might be a more general solution. |
|
I close this in favor of #25766. |
Fix #25506