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

fix: check/fix return types and tighten argument types #22

Merged
merged 8 commits into from
Aug 30, 2023

Conversation

jpivarski
Copy link
Member

No description provided.

@jpivarski
Copy link
Member Author

I used @inferred everywhere that it can be used (thanks, @Moelf!).

The REPL outputs also look right, though I still wonder about Any[1.1, 2.2, 3.3], etc.

julia> layout = AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5])
5-element AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}:
 1.1
 2.2
 3.3
 4.4
 5.5

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Float64

julia> layout = AwkwardArray.ListOffsetArray([0, 3, 3, 5],
                  AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
              )
3-element AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 Any[1.1, 2.2, 3.3]
 0-element AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}
 Any[4.4, 5.5]

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}

julia> layout = AwkwardArray.ListArray([0, 3, 3], [3, 3, 5],
                  AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
              )
3-element AwkwardArray.ListArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 Any[1.1, 2.2, 3.3]
 0-element AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}
 Any[4.4, 5.5]

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}

julia> layout = AwkwardArray.RegularArray(
           AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5, 6.6]),
           3,
       )
2-element AwkwardArray.RegularArray{AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 Any[1.1, 2.2, 3.3]
 Any[4.4, 5.5, 6.6]

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}

julia> layout = AwkwardArray.StringOffsetArray(
           [0, 3, 8, 9, 11, 14, 18],
           "heythere\$¢€💰",
       )
6-element AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{UInt8, Vector{UInt8}, :char}, :string}:
 "hey"
 "there"
 "\$"
 "¢"
 ""
 "💰"

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 String

julia> layout = AwkwardArray.StringArray(
           [0, 3, 8, 9, 11, 14],
           [3, 8, 9, 11, 14, 18],
           "heythere\$¢€💰",
       )
6-element AwkwardArray.ListArray{Vector{Int64}, AwkwardArray.PrimitiveArray{UInt8, Vector{UInt8}, :char}, :string}:
 "hey"
 "there"
 "\$"
 "¢"
 ""
 "💰"

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 String

julia> layout = AwkwardArray.StringRegularArray(
           "heyyou", 3
       )
2-element AwkwardArray.RegularArray{AwkwardArray.PrimitiveArray{UInt8, Vector{UInt8}, :char}, :string}:
 "hey"
 "you"

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 String

julia> layout = AwkwardArray.RecordArray(
           NamedTuple{(:a, :b)}((
               AwkwardArray.PrimitiveArray([1, 2, 3]),
               AwkwardArray.ListOffsetArray(
                   [0, 3, 3, 5],
                   AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
               ),
           )),
       )
3-element AwkwardArray.RecordArray{NamedTuple{(:a, :b), Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}}, :default}:
 AwkwardArray.Record{AwkwardArray.RecordArray{NamedTuple{(:a, :b), Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}}, :default}}(Any[#= circular reference @-2 =#], 1)
 AwkwardArray.Record{AwkwardArray.RecordArray{NamedTuple{(:a, :b), Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}}, :default}}(Any[#= circular reference @-2 =#], 2)
 AwkwardArray.Record{AwkwardArray.RecordArray{NamedTuple{(:a, :b), Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}}, :default}}(Any[#= circular reference @-2 =#], 3)

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 AwkwardArray.Record{AwkwardArray.RecordArray{NamedTuple{(:a, :b), Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}}, :default}}

julia> layout = AwkwardArray.TupleArray(
           (
               AwkwardArray.PrimitiveArray([1, 2, 3]),
               AwkwardArray.ListOffsetArray(
                   [0, 3, 3, 5],
                   AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
               ),
           ),
       )
3-element AwkwardArray.TupleArray{Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}:
 AwkwardArray.Tuple{AwkwardArray.TupleArray{Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}}(Any[#= circular reference @-2 =#], 1)
 AwkwardArray.Tuple{AwkwardArray.TupleArray{Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}}(Any[#= circular reference @-2 =#], 2)
 AwkwardArray.Tuple{AwkwardArray.TupleArray{Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}}(Any[#= circular reference @-2 =#], 3)

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 AwkwardArray.Tuple{AwkwardArray.TupleArray{Tuple{AwkwardArray.PrimitiveArray{Int64, Vector{Int64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}}

julia> layout = AwkwardArray.IndexedArray(
           [4, 3, 3, 0],
           AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
       )
4-element AwkwardArray.IndexedArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 5.5
 4.4
 4.4
 1.1

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Float64

julia> layout = AwkwardArray.IndexedOptionArray(
           [4, 3, 3, -1, -1, 0],
           AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
       )
6-element AwkwardArray.IndexedOptionArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 5.5
 4.4
 4.4
  missing
  missing
 1.1

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Union{Missing, Float64}

julia> layout = AwkwardArray.ByteMaskedArray(
           [false, true, true, false, false],
           AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
           valid_when = false,
       )
5-element AwkwardArray.ByteMaskedArray{Vector{Bool}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 1.1
  missing
  missing
 4.4
 5.5

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Union{Missing, Float64}

julia> layout = AwkwardArray.BitMaskedArray(
           BitVector([false, true, true, false, false]),
           AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
           valid_when = false,
       )
5-element AwkwardArray.BitMaskedArray{AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 1.1
  missing
  missing
 4.4
 5.5

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Union{Missing, Float64}

julia> layout = AwkwardArray.UnmaskedArray(
            AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
        )
5-element AwkwardArray.UnmaskedArray{AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}:
 1.1
 2.2
 3.3
 4.4
 5.5

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Float64

julia> layout = AwkwardArray.UnionArray(
           Vector{Int8}([0, 0, 0, 1]),
           [0, 1, 2, 0],
           (
               AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3]),
               AwkwardArray.ListOffsetArray(
                   [0, 2],
                   AwkwardArray.PrimitiveArray([4.4, 5.5]),
               ),
           ),
       )
4-element AwkwardArray.UnionArray{Vector{Int8}, Vector{Int64}, Tuple{AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, AwkwardArray.ListOffsetArray{Vector{Int64}, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}, :default}}, :default}:
 1.1
 2.2
 3.3
  Any[4.4, 5.5]

julia> Base.return_types(getindex, (typeof(layout), typeof(1)))
1-element Vector{Any}:
 Union{Float64, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}}

@jpivarski
Copy link
Member Author

There are some situations, like passing a Symbol to getindex to get a RecordArray field (or an Int for TupleArray) that cannot know the output type; it depends on the value of a function argument.

https://github.com/jpivarski/AwkwardArray.jl/blob/1903f4bb4592507055cb8ca0d7bfc2e2a2b88bad/src/AwkwardArray.jl#L986-L989

With

layout = AwkwardArray.RecordArray(
    NamedTuple{(:a, :b)}((
        AwkwardArray.PrimitiveArray([1, 2, 3]),
        AwkwardArray.ListOffsetArray(
            [0, 3, 3, 5],
            AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
        ),
    )),
)

and

@inferred layout[3][:a]

I get

return type Int64 does not match inferred return type Union{Int64, AwkwardArray.PrimitiveArray{Float64, Vector{Float64}, :default}}

because of course. Same for the option-types of X, which are predicted to return Union{Missing, X}.

@jpivarski jpivarski linked an issue Aug 29, 2023 that may be closed by this pull request
@jpivarski jpivarski linked an issue Aug 29, 2023 that may be closed by this pull request
@Moelf
Copy link
Member

Moelf commented Aug 29, 2023

right, the only way for this to be inferrable

@inferred layout[3][:a]

is if layout[3]'s type encodes :a <-> Type information (e.g. like a NamedTuple). So I would say it's not worth the latency cost probably

Comment on lines +980 to +984
@inferred layout[3]
@inferred layout[1:3]
@inferred layout[:a][3]
@inferred layout[:b][3]
@inferred layout[:b][3][1]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With stronger typing, some of these can be inferred, but others can't:

@inferred layout[:a][3]      # cool: these can be inferred!
@inferred layout[:b][3]
@inferred layout[:b][3][1]

@inferred layout[3][:a]      # but these fail!
@inferred layout[3][:b]
@inferred layout[3][:b][1]

I thought maybe adding more types to the Record struct (layout[3]) and associated functions would do it, but apparently no, or not yet.

@jpivarski jpivarski marked this pull request as ready for review August 30, 2023 00:29
@jpivarski jpivarski enabled auto-merge (squash) August 30, 2023 00:29
@jpivarski jpivarski merged commit aace668 into main Aug 30, 2023
2 checks passed
@jpivarski jpivarski deleted the jpivarski/check-all-return-types branch August 30, 2023 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants