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

Bug in merge for NamedTuple #43045

Closed
bkamins opened this issue Nov 11, 2021 · 6 comments · Fixed by #43143
Closed

Bug in merge for NamedTuple #43045

bkamins opened this issue Nov 11, 2021 · 6 comments · Fixed by #43143
Assignees

Comments

@bkamins
Copy link
Member

bkamins commented Nov 11, 2021

Here is a MWE:

julia> x = Iterators.reverse(pairs((a=1,b=2)))
pairs(::NamedTuple) with 2 entries:
  :b => 2
  :a => 1

julia> merge(NamedTuple(), x)
(a = 1, b = 2)

The problem is that merge uses only :data field, but ignores the order specified by the :itr field.

@JeffBezanson
Copy link
Member

Huh --- I'm not sure the use of Pairs in this reverse method is valid. It's possible to construct one with any keys you want, but I don't think the type is intended to provide general "views" of collections.

@bkamins
Copy link
Member Author

bkamins commented Nov 11, 2021

For a reference: it is not NamedTuple specific:

julia> dump(Iterators.reverse(pairs((a=11,b=22,c=33,d=44))))
Base.Iterators.Pairs{Symbol, Int64, Base.Iterators.Reverse{NTuple{4, Symbol}}, NamedTuple{(:a, :b, :c, :d), NTuple{4, Int64}}}
  data: NamedTuple{(:a, :b, :c, :d), NTuple{4, Int64}}
    a: Int64 11
    b: Int64 22
    c: Int64 33
    d: Int64 44
  itr: Base.Iterators.Reverse{NTuple{4, Symbol}}
    itr: NTuple{4, Symbol}
      1: Symbol a
      2: Symbol b
      3: Symbol c
      4: Symbol d

julia> dump(Iterators.reverse(pairs((11,22,33,44))))
Base.Iterators.Pairs{Int64, Int64, StepRange{Int64, Int64}, NTuple{4, Int64}}
  data: NTuple{4, Int64}
    1: Int64 11
    2: Int64 22
    3: Int64 33
    4: Int64 44
  itr: StepRange{Int64, Int64}
    start: Int64 4
    step: Int64 -1
    stop: Int64 1

julia> dump(Iterators.reverse(pairs([11,22,33,44])))
Base.Iterators.Pairs{Int64, Int64, Base.Iterators.Reverse{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}, Vector{Int64}}
  data: Array{Int64}((4,)) [11, 22, 33, 44]
  itr: Base.Iterators.Reverse{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}
    itr: LinearIndices{1, Tuple{Base.OneTo{Int64}}}
      indices: Tuple{Base.OneTo{Int64}}
        1: Base.OneTo{Int64}
          stop: Int64 4

@JeffBezanson
Copy link
Member

Right; I'm wondering for example if that method should reverse the collection too, or be replaced with several more specific methods, or something else.

@JeffBezanson
Copy link
Member

Aha:

values(v::Pairs) = getfield(v, :data) # TODO: this should be a view of data subset by itr

So Pairs is enough of a view to write a comment about it, but not enough of a view to actually work that way :)

One thing at stake here is that if Pairs can do arbitrary re-orderings, then merge(::NamedTuple, ::Pairs{NamedTuple}) cannot be optimized.

@bkamins
Copy link
Member Author

bkamins commented Nov 12, 2021

I would prioritize correctness over speed (as clearly what I report is a bug). I think we could allow :itr to be nothing, in which case the order of :data could be taken (as this is probably 99% of cases).

I have not checked if it would break anything but it seems it should not.

@JeffBezanson JeffBezanson added the triage This should be discussed on a triage call label Nov 15, 2021
@JeffBezanson
Copy link
Member

Idea: instead of implementing reverse(::Pairs) = Pairs(...), return a Reverse iterator for that, and implement iterate for Reverse{<:Pairs}.

@JeffBezanson JeffBezanson self-assigned this Nov 19, 2021
vtjnash pushed a commit that referenced this issue Nov 19, 2021
@JeffBezanson JeffBezanson removed the triage This should be discussed on a triage call label Dec 2, 2021
LilithHafner pushed a commit to LilithHafner/julia that referenced this issue Feb 22, 2022
LilithHafner pushed a commit to LilithHafner/julia that referenced this issue Mar 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants