Skip to content

Stricter tuple destructuring. Error on (a, b) = (1, 2, 3) #37132

@goretkin

Description

@goretkin

Current behavior

julia> (a, b) = (1, 2, 3) # or `a, b = (1, 2, 3)`
(1, 2, 3)

julia> a
1

julia> b
2

I think I'd like an error. This would be breaking on Julia 1.0, but @DilumAluthge suggested I open an issue to keep track of it possibly for Julia 2.0.

As mentioned in the manual, a Tuple can be thought of a positional-argument-only function call without the function. A function call binds values in the calling context to the formal arguments in the function body context, and so it could be nice to have tuple assignment behave more similarly to that binding process. In other words, you cannot call f(a, b) as f(1, 2, 3).

In other words still, if tuple destructuring were more strict, then the two functions g and h would be equivalent (up to error type):

function g(args)
  function f(a, b)
    a * b
  end

  f(args...)
end

function h(args)
  let (a, b) = args
    a * b
  end
end
julia> h((2,3))
6

julia> g((2,3))
6

julia> g((2,3,4))
ERROR: MethodError: no method matching (::var"#f#59")(::Int64, ::Int64, ::Int64)
Closest candidates are:
  f(::Any, ::Any)

julia> h((2,3,4))
6

h((2,3,4)) would throw some kind of error (not MethodError).

This is what happens today:

julia> Meta.@lower (a, b) = c
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = Base.indexed_iterate(c, 1)
│   %2 = Core.getfield(%1, 1)
│        a = %2
│        #s332 = Core.getfield(%1, 2)
│   %5 = Base.indexed_iterate(c, 2, #s332)
│   %6 = Core.getfield(%5, 1)
│        b = %6
└──      return c
))))

If the strict behavior is desired, I don't know whether to enforce it with a length call, or whether to more generally check that the iterator is empty at the end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingThis change will break codecompiler:loweringSyntax lowering (compiler front end, 2nd stage)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions