Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 498
Phillip Cloud Avatar asked May 16 '11 02:05

Phillip Cloud


2 Answers

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.

like image 95
Vatine Avatar answered Oct 12 '22 23:10

Vatine


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.

like image 26
Nietzche-jou Avatar answered Oct 12 '22 23:10

Nietzche-jou