Search code examples
pythonlistlispcommon-lispiterable-unpacking

Tuple Unpacking Similar to Python, but in Common Lisp


Is there a way to assign the values of a list to a list of symbols in Common Lisp similar to the way that you can assign the values of tuple to variables in Python?

x, y, z = (1, 2, 3)

Something like

(setq '(n p) '(1 2))

Where n and p are now equal to 1 and 2, respectively. The above was just how I was thinking about it in my head, but it doesn't work. I tried using apply as follows:

(apply setq '('(n p) '(1 2)))

I'm new to Lisp, so if this is something that's blatantly obvious, try not to be too harsh and please point me in the right direction! Thanks.

PS: I've seen the post on doing this in Scheme and a similar one on tuple expansion in Common Lisp, but those weren't very helpful in answering my question 1) because I'm not using Scheme, and 2) because the highest ranked answer was just the word apply.


Solution

  • Use DESTRUCTURING-BIND, which can do a whole heck of a lot more than tuple unpacking. Like assignment by keywords, and optional parameters, etc. Really, anything you can do with a function's parameter list.

    But if you don't actually have a list to destructure, and want to set a bunch of variables at once, use PSETF:

    (psetf n 1
           p 2)
    

    You can also use SETF, but PSETF is a closer analog of tuple assignment: it works for swapping/permuting values, for instance.

    # Python
    n, p = p, n
    x, y, z = z, x, y
    
    ;; Lisp
    (psetf n p
           p n)
    (psetf x z
           y x
           z y)
    

    Actually you could probably get away with a mundane LET.

    Also, don't bother with SETQ for anything. Use SETF/PSETF because they are better, and moreover the only way to perform certain types of assignments.