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

range map-broadcast inconsistency #54364

Open
aplavin opened this issue May 5, 2024 · 4 comments
Open

range map-broadcast inconsistency #54364

aplavin opened this issue May 5, 2024 · 4 comments
Labels
domain:ranges Everything AbstractRange

Comments

@aplavin
Copy link
Contributor

aplavin commented May 5, 2024

# for -: broadcast returns a range, map materialized
julia> .-(1:3)
-1:-1:-3

julia> map(-, 1:3)
3-element Vector{Int64}:
 -1
 -2
 -3

# for type: map returns a range, broadcast materialized
julia> Float64.(1:3)
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> map(Float64, 1:3)
1.0:1.0:3.0

Not sure which behavior is intended, but it could use more consistency I guess.

@jariji
Copy link
Contributor

jariji commented May 5, 2024

Both of these functions have a rather wide interface, so the inconsistency doesn't violate any requirement of their specification afaict.

It would be nice if they guaranteed the output type match the input type, but that's rather out of reach in 1.x I think. #32081

@aplavin
Copy link
Contributor Author

aplavin commented May 6, 2024

the inconsistency doesn't violate any requirement of their specification

Sure, same as Julia inferring anything as Any.

However, this is still an inconsistency, quite an unintuitive one: there's no single answer to what has a better "chance" of preserving a range, f.(x) or map(f, x).

@nsajko nsajko added the domain:ranges Everything AbstractRange label May 6, 2024
@nsajko
Copy link
Contributor

nsajko commented May 6, 2024

For general f, neither f.(range) nor map(f, range) can return back a range. Thus this requires special-casing the function (or type) f. An endless game of whack-a-mole?

@aplavin
Copy link
Contributor Author

aplavin commented May 6, 2024

Thus this requires special-casing the function (or type) f. An endless game of whack-a-mole?

Totally, I agree with you here.
Would prefer something like islinear() trait for functions that makes both f.(::Range)::Range and map(f, ::Range)::Range...

But here we are working with the current situation. This special-casing exists in Julia already, as seen from the examples above.
This map vs broadcast split makes it impossible to predict the return type of such functions, and makes this optimization completely non-discoverable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:ranges Everything AbstractRange
Projects
None yet
Development

No branches or pull requests

3 participants