Question

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.

Was it helpful?

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.

OTHER TIPS

Sounds like destructuring-bind (it's way at the bottom) may do what you want.

Also, the HyperSpec description, but I think the other link demonstrates it better.

(destructuring-bind (x y z) (list 1 2 3) (+ x y z))

For the case where you have a list and want to assign its values to multiple variables, DESTRUCTURING-BIND is the way to go.

However, for the pythonic "return a list or tuple, use a list or tuple of variables to assign to" case, it's (probably) lispier to use multiple return values and MULTIPLE-VALUE-BIND.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top