-
Notifications
You must be signed in to change notification settings - Fork 102
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
base: main
Are you sure you want to change the base?
Conversation
Is it possible for after I don't really know much about what this code is doing but it looks alright to me. |
src/execution.jl
Outdated
@@ -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.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
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
```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more selective test, adding an error message in unrecognized cases.
The only cases I can think of that would initially parse but than trigger the error are the invalid forms (; x, y=3) = z
and (x, y; z) = q
.
This isn't even about the interpolation with dollar. For example, this also fails:
|
I don't think that's possible, at least assuming valid Julia code is passed to |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added tests for interpolated values both for the tuple and named tuple case (though I don't think the code I changed is specific to interpolation in any way).
src/execution.jl
Outdated
@@ -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) |
There was a problem hiding this comment.
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
```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to fix this for the general case
@@ -345,7 +345,18 @@ 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 !all(arg -> isa(arg, Symbol), args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so long as we're fixing this, let's fix this for real. There are two cases of destructuring to support: namedtuple and possibly nested tuple (which may contain namedtuple).
Let's structure the code then as:
elseif isa(lhs, Expr) && lhs.head == :tuple && length(args) == 1 && lhs.args[1].head === :parameters && all(arg->isa(arg, Symbol)), lhs.args[1].args)
append!(vars, lhs.args[1].args)
elseif isa(lhs, Expr) && lhs.head == :tuple
for arg in lhs.args
if arg isa Symbol
push!(vars, arg)
else
collectvars(arg, vars)
end
end
elseif
and let's also add a test for (a, (b, c)) = rhs
as well as (a, (;x, y)) = rhs
e.g.
currently fails at macro expansion