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

Support for named tuple destructuring #362

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

yha
Copy link

@yha yha commented Apr 9, 2024

e.g.

@benchmark let 
    (; x, y) = $p
    f(x,y)
end

currently fails at macro expansion

@Zentrik
Copy link
Contributor

Zentrik commented Apr 23, 2024

Is it possible for after args = first(args).args for args to still be an Expr? Should we keep expanding till it's not?

I don't really know much about what this code is doing but it looks alright to me.

@@ -346,7 +346,12 @@ function collectvars(ex::Expr, vars::Vector{Symbol}=Symbol[])
if isa(lhs, Symbol)
push!(vars, lhs)
elseif isa(lhs, Expr) && lhs.head == :tuple
append!(vars, lhs.args)
args = lhs.args
if !isempty(args) && isa(first(args), Expr)

This comment was marked as resolved.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we know if this is robust across julia versions? I'd like to see a more selective test, that perhaps checks the head of some of these exprs. to see that they are namedtuples.

e.g. probably we should see :parameters somewhere in here:

julia> dump(:((; x, y) = a))
Expr
  head: Symbol =
  args: Array{Any}((2,))
    1: Expr
      head: Symbol tuple
      args: Array{Any}((1,))
        1: Expr
          head: Symbol parameters
          args: Array{Any}((2,))
            1: Symbol x
            2: Symbol y
    2: Symbol a
    ```

@willow-ahrens
Copy link
Collaborator

This isn't even about the interpolation with dollar. For example, this also fails:

@benchmark let 
           (; x, y) = p
           f(x,y)
       end

@yha
Copy link
Author

yha commented May 7, 2024

Is it possible for after args = first(args).args for args to still be an Expr? Should we keep expanding till it's not?

I don't really know much about what this code is doing but it looks alright to me.

I don't think that's possible, at least assuming valid Julia code is passed to @benchmark. I believe the args after that line can be an Expr only in a case like (; x = (a,b), y) which is not a valid lhs for assignment (and in that case the head of that would be :kw, not another :tuple, so it would require more complicated recursion if the goal is to make a better error message. But it's an unlikely mistake from the user anyway)

Copy link
Collaborator

@willow-ahrens willow-ahrens left a comment

Choose a reason for hiding this comment

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

This is a good start, just a few small tweaks! Thanks for your contribution!

@benchmark (; foo, bar) = (foo="good", bar="good") setup = (foo = "bad"; bar = "bad") teardown = @test(
foo == "good" && bar == "good"
)
end
Copy link
Collaborator

Choose a reason for hiding this comment

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

These tests are good, but if I understand correctly, I think this is missing the case where we interpolate a value from local scope with dollar, since that's part of the code that this PR changes.

@@ -346,7 +346,12 @@ function collectvars(ex::Expr, vars::Vector{Symbol}=Symbol[])
if isa(lhs, Symbol)
push!(vars, lhs)
elseif isa(lhs, Expr) && lhs.head == :tuple
append!(vars, lhs.args)
args = lhs.args
if !isempty(args) && isa(first(args), Expr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we know if this is robust across julia versions? I'd like to see a more selective test, that perhaps checks the head of some of these exprs. to see that they are namedtuples.

e.g. probably we should see :parameters somewhere in here:

julia> dump(:((; x, y) = a))
Expr
  head: Symbol =
  args: Array{Any}((2,))
    1: Expr
      head: Symbol tuple
      args: Array{Any}((1,))
        1: Expr
          head: Symbol parameters
          args: Array{Any}((2,))
            1: Symbol x
            2: Symbol y
    2: Symbol a
    ```

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 this pull request may close these issues.

None yet

3 participants