-
-
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
ntuple eltype depends on tuple length for UInt64 #55790
Comments
Smaller integer ones are broken for all too. This may fix that @inline function Base.ntuple(f::F, n::T) where {F, T<:Integer}
# marked inline since this benefits from constant propagation of `n`
t = n == T(0) ? () :
n == T(1) ? (f(T(1)),) :
n == T(2) ? (f(T(1)), f(T(2))) :
n == T(3) ? (f(T(1)), f(T(2)), f(T(3))) :
n == T(4) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4))) :
n == T(5) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5))) :
n == T(6) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5)), f(T(6))) :
n == T(7) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5)), f(T(6)), f(T(7))) :
n == T(8) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5)), f(T(6)), f(T(7)), f(T(8))) :
n == T(9) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5)), f(T(6)), f(T(7)), f(T(8)), f(T(9))) :
n == T(10) ? (f(T(1)), f(T(2)), f(T(3)), f(T(4)), f(T(5)), f(T(6)), f(T(7)), f(T(8)), f(T(9)), f(T(10))) :
Base._ntuple(f, n)
return t
end
function Base._ntuple(f::F, n) where F
@noinline
(n >= 0) || throw(ArgumentError(LazyString("tuple length should be ≥ 0, got ", n)))
([f(i) for i = Base.OneTo(n)]...,)
end but I am not sure about |
I think it probably makes more sense to change just |
On main branch, `Tables.partitions` fails on table with more than 10 columns. The (somewhat convoluted) reason is that julia `ntuple` function when fed a `UInt64` as second argument, casts it to `Int` only if it is `<= 10` (see JuliaLang/julia#55790). This works in our favor for small `n` (number of columns), as the function `ColumnConversionData` expects a `Int`, not a `UInt64`, but for larger `n` attempting to collect a `Tables.partitions` fails. The first commits is a minimal fix + test, whereas the second commit also adds a small refactor to simplify code and make it more robust to this.
not every I guess that's a useless concern bc if you are trying to make a tuple with length >64 bits you will probably find more serious obstacles very quickly |
I was hasty and didn't read this thread properly, and went and implemented something very similar to @tomaklutfu's proposal in #55825. I do think respecting the type given by the user makes more sense. If a user gives me a Note also that currently this is extra inconsistent julia> ntuple(identity, UInt64(11))
(0x0000000000000001, 0x0000000000000002, 0x0000000000000003, 0x0000000000000004, 0x0000000000000005, 0x0000000000000006, 0x0000000000000007, 0x0000000000000008, 0x0000000000000009, 0x000000000000000a, 0x000000000000000b)
julia> ntuple(identity, UInt8(11))
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) That's because |
I see two possible fixes:
Because this impacts public API, I think it's worth talking about at triage. (triage is a biweekly call which is open to the public and can be found on the Julia community calendar) |
on further thought, I think the reason is short: |
I'm seeing a lot of support for option 1 and no explicit support for option 2. @tomaklutfu and @mhauru have provided implementations for option 2, but I haven't seen either of them state a preference for it over option 1 (please say so if you do have that preference). Unless anyone speaks up in favor of preserving the argument type, I think it makes sense to go ahead and implement option 1. |
I did originally think that option 2 made more sense, but the index point is valid, and I'm happy to go with 1, especially since its supported by people with more experience with the codebase than me (that's almost everyone). |
We say ith index but do we say index should be |
The array interface requires custom arrays to define julia> x = Base.OneTo(typemax(UInt64))
Base.OneTo(18446744073709551615)
julia> x[typemax(Int) + big(10)]
0x8000000000000009 ) So |
Triage dixit: It should always return Ints, the indices of a tuple are Ints. |
Both on julia 1.10.5 and julia 1.11.0-rc3, calling
ntuple(f, n::UInt64)
gives the following unexpected behavior:I imagine this is due to the fact that for
n <= 10
there is an hard-coded version usingInt
, whereas the generic fallback respects theUInt64
eltype. I suppose this is a pretty rare corner case (99% of the time I suspectntuple
is called withn::Int
), but it caused some hard to figure out bug in some library code, so I thought it was worth reporting.The text was updated successfully, but these errors were encountered: