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

float implicitly broadcasts #49929

Open
oscardssmith opened this issue May 22, 2023 · 12 comments
Open

float implicitly broadcasts #49929

oscardssmith opened this issue May 22, 2023 · 12 comments
Labels
deprecation This change introduces or involves a deprecation
Milestone

Comments

@oscardssmith
Copy link
Member

float([2,3]) == [2.0, 3.0], but we should probably require this to be spelled float.([2,3]) (and my guess is this deprecation was missed in the 0.7 cycle. In the meantime, should we deprecate this?

@oscardssmith oscardssmith added the deprecation This change introduces or involves a deprecation label May 22, 2023
@oscardssmith oscardssmith added this to the 2.0 milestone May 22, 2023
@KristofferC
Copy link
Member

This is intentional. float here is not broadcasted but takes a vector as the domain of its input.

@oscardssmith
Copy link
Member Author

right, but to me this really feels like broadcasting. It's not like it's converting a matrix to a float. It's taking all the entries and converting them separately.

@KristofferC
Copy link
Member

This has been discussed before. I can't find the issue now but I'm pretty sure @stevengj was involved.

@adienes
Copy link
Contributor

adienes commented May 22, 2023

compare to big([1,2,3]) and string([1,2,3])

@KristofferC
Copy link
Member

KristofferC commented May 22, 2023

Here's some of the previous discussion I mentioned #18495. Also #22236 (comment).

@adienes
Copy link
Contributor

adienes commented May 22, 2023

even given those reasons to keep the functionality, it should still be float! and complex! though right? for the same reason as in #32528 that String(::Vector{UInt8}) should be named String!

@KristofferC
Copy link
Member

It doesn't mutate the input argument so why should it have a !?

@adienes
Copy link
Contributor

adienes commented May 22, 2023

woops. I was going off some of the earlier discussion in that issue you linked where it appears float did not copy? but I should have actually tried it.

given that float(x) seems now to do the same thing as float.(x) (besides participate differently in broadcast fusion) then I have an even harder time understanding the argument to keep the method

@giordano
Copy link
Contributor

given that float(x) seems now to do the same thing as float.(x)

It doesn't the same thing, float(array) is no-op when array is already all floats, broadcast always creates a new array (and I've taken advantage of this in some packages).

@adienes
Copy link
Contributor

adienes commented May 23, 2023

to me that seems like the worst and most dangerous of all worlds. it sometimes copies and sometimes doesn't?

I guess so

julia> x = rand(3);

julia> float(x)[1] = 100;

julia> x
3-element Vector{Float64}:
 100.0
   0.3173450352923628
   0.5859919943733706

julia> 

julia> x = rand(1:10, 3);

julia> float(x)[1] = 100;

julia> x
3-element Vector{Int64}:
 2
 3
 9

@timholy
Copy link
Member

timholy commented May 24, 2023

It's the same thing that convert(AbstractVector{Float64}, v) would do:

julia> v = [1.0,2.0,3.0]
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> convert(AbstractVector{Float64}, v) === v
true

@adienes
Copy link
Contributor

adienes commented May 25, 2023

I did a little poking around and comparing to similar functions and I apologize for + retract some of my initial incredulity. here's what I got:

Function(s) aliasing explicitly documented as such
convert(typeof(x), x) usually yes
collect(eltype(x), x) and similar(eltype(t), t) never no
real(x) and conj(x) always when <: Real, otherwise never yes
complex(x) yes for complex-y type, otherwise usually not no
imag(x) never yes
float(x) yes for float-y types, otherwise usually not no

Actionable:

As for this issue, while it seems a bit more reasonable now, I still think the argument for float as a method is sort of weak. All of the related methods real, imag, conj, and complex work with integral types as well as float types, so float is kind of the only odd one out that is about precision more so than number domain. That is, by the same argument to keep float as a copy-free convert, I think one could argue that e.g. trunc(Int, AbstractArray{<:Integer}) should also alias (which it does not).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecation This change introduces or involves a deprecation
Projects
None yet
Development

No branches or pull requests

5 participants