-
-
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
0.6 undocumented incompatibility/change? #20946
Comments
There is a NEWS entry about it. |
You're referring to this entry?
With all respect, that's probably the least intuitive explanation for what's happening here that I can imagine. |
Perhaps make a PR with something along the line "Consequently, |
Just to clarify, |
Why is that confusing? It works just as for |
The fact that it works the same as the scalar ops is good. There's a separate issue that perhaps the scalar ops should have different behaviors than they do, but that's a different issue. |
I think I'm in agreement with @sbromberger here. This change does make it harder to write code that works the same on both 32 and 64-bit systems. I've been playing around with this, and the results don't really mesh with my intuition. Some interesting examples--can you predict the output types on 32-bit and 64-bit systems?: f(x) = (x.+=1; x)
g(x) = x.+1
x = UInt64[1,2,3]
y = UInt32[1,2,3]
z = Int32[1,2,3]
f(x)
f(y)
f(z)
g(x)
g(y)
g(z) |
This is confusing behavior to me: julia> function f(x)
println("eltype in ", eltype(x))
v = x + 1
println("eltype out ", eltype(v))
return v
end;
julia> f(Int32[1,2,3]);
eltype in Int32
eltype out Int32
julia> f(Int32(1));
eltype in Int32
eltype out Int64 |
@KristofferC, that make sense. And from my perspective, it is also confusing to me when my julia> function f(x)
println("type in ", typeof(x))
x += 1
println("type out ", typeof(x))
return x
end;
julia> f(UInt32[1,2,3]);
type in Array{UInt32,1}
type out Array{Int64,1} |
So do you expect |
Your array type didn't change. You created a brand new array. |
It it kind of annoying that |
I'm also of the opinion that this behavior of integers is unfortunate but it all roots on the, also unfortunate IMO, decision that integers default to int64. |
X-ref: #19669 If you need to preserve the type of your container you now have many options:
|
What would you propose that integers default to? |
@pabloferz: I was actually think more in terms of scalar operations, where I often have to take pains to get arguments to the same type, e.g. when writing things like |
I would have preferred that they defaulted to int32, both in 32 and 64 bits systems |
@StefanKarpinski I was referring to the OP for the cases where you have to work with arrays. For scalars maybe #19992 could be relevant. There it is proposed to make |
@yuyichao no, in that case I expect to have a
|
@KristofferC said:
Sorry, you're right. What I meant (and should have said) was that my variable type changed. |
Haven't we been here before, e.g. #1641? This feels a lot like a regression. |
It is not a "regression" because it was an intentional change. Writing generic code you should not really care if your function get passed an array or a number and you want to apply an operation to all the elements. It is inconsistent to me to return different element types depending on if The comment you linked are from five years ago. A lot of things have changed since then. |
It's probably not that constructive for two Swedes to discuss the meaning of English words but I'm fairly certain you can regress even if you do it by intention. In this case it's a regression to the state of Julia before #1641, which was also an intentional change. (Personally I'd solve both the problem of blowing up arrays and consistency between arrays and scalars by promoting Float32, Float64 to Float32, but that has been hard to sell.) |
Yes. "principle of least surprise", and all. |
@KristofferC What's your Julia version? I got this with your code: julia> function f(x)
println("eltype in ", eltype(x))
v = x + 1
println("eltype out ", eltype(v))
return v
end;
julia> f(Int32[1,2,3]);
eltype in Int32
eltype out **Int64**
julia> f(Int32(1));
eltype in Int32
eltype out Int64 And BTW this is also annoying to me: julia> f(Int64(1));
eltype in Int64
eltype out Int64
julia> f(UInt32(1));
eltype in UInt32
eltype out Int64
julia> f(UInt64(1));
eltype in UInt64
eltype out UInt64 Although I can understand what happened here. |
@sunoru This was in 0.5 to show the previous behavior. Promotion between scalars can be confusing sometimes yes. I think there is an issue dealing with it, with a suggestion to make it more intuitive, but I can't find it right now. |
@KristofferC I see. I agree with you. |
If integers defaulted to
Of course, that could imply making an extra copy of an array, which would be unfortunate. If we really think these cases are bugs, maybe a type assertion instead? |
I would say that has more to do with |
Ran into this issue on 0.6 and found another error when the julia> function zero_plus_one()
a =zeros(UInt32, 2)
return a .+= 1
end
zero_plus_one (generic function with 1 method)
julia> zero_plus_one()
2-element Array{UInt32,1}:
0x00000001
0x00000001
julia> function zero_plus_one()
a =zeros(UInt32, 2)
return 3, a .+= 1
end
zero_plus_one (generic function with 1 method)
julia> zero_plus_one()
ERROR: MethodError: no method matching broadcast!(::##9#10, ::Tuple{Int64,Array{UInt32,1}}, ::Tuple{Int64,Array{UInt32,1}})
Closest candidates are:
broadcast!(::Any, ::AbstractArray, ::Any, ::Any...) where N at broadcast.jl:204
broadcast!(::Tf, ::Union{SparseMatrixCSC, SparseVector}) where Tf at sparse/higherorderfns.jl:98
broadcast!(::Tf, ::Union{SparseMatrixCSC, SparseVector}, ::Union{SparseMatrixCSC, SparseVector}, ::Union{SparseMatrixCSC, SparseVector}...) where {Tf, N} at sparse/higherorderfns.jl:111
...
Stacktrace:
[1] zero_plus_one() at ./REPL[10]:3 Hopefully this is not expected. |
The lowering is the same on 0.5. It is assigning to |
what if you change
to
?
I think the issue is that the precedence for |
per https://discourse.julialang.org/t/is-this-expected-behavior-0-5-to-0-6-breakage/2534/7
In 0.5:
In 0.6:
(Is there a reason this change was made? FWIW, I prefer the old behavior. Changing the type out from under me broke a bunch of things, most significantly some code for generating random graphs:
Unless you know that
MersenneTwister
's seed is aVector{UInt32}
, you wouldn't know that adding1
to it would cause a type change and subsequent failure. Ironically, if it were aVector{Char}
, everything would have just worked:I couldn't find anything in NEWS.md on this change, so at a minimum, I think a note would be warranted if this new behavior is intended.
The text was updated successfully, but these errors were encountered: