4

I have a function that return two splited list like below :

((1 . 2) (3 . 4) (5 . 7))
((8 . 9) (10 . 23) (30 . 20))

Is there any resource in common lisp to do like python

a,b = 1,2
a = 1 
b = 2 
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • You can try to return `(cons a b)`, and get the 2 values with `car` and `cdr` – Colin Yang Jun 05 '16 at 06:41
  • Possible duplicate of [values function in Common Lisp](http://stackoverflow.com/questions/22795608/values-function-in-common-lisp) – sds Jun 05 '16 at 14:05
  • The question title is a bit misleading, it would be more self-explaining something like "How to bind a returned tuple to several variables in Common Lisp?", or "How to return multiple values and bind them later?". I hope you agree with that. – ssice Jun 07 '16 at 12:38

2 Answers2

16

There are two options. First, you can return multiple values with VALUES. You can then use MULTIPLE-VALUE-BIND to bind the return values to different variables.

(defun foo ()
  (values '((1 . 2) (3 . 4) (5 . 7))
          '((8 . 9) (10 . 23) (30 . 20))))

(multiple-value-bind (a b) (foo)
  (format t "~&A: ~s~%B: ~s~%" a b))
; A: ((1 . 2) (3 . 4) (5 . 7))
; B: ((8 . 9) (10 . 23) (30 . 20))

This is a little different from Python, because you can call the function as if it only returned one value, and the other values will be silently discarded. Multiple return values are usually used when the first value makes sense on its own, and the others are just supplementary information (see for example FLOOR).

In this case it seems like the two values are related to each other (so that it never makes sense to use only the first value). So in this case it's probably better to return a list, or a cons-cell, instead. You can use DESTRUCTURING-BIND to assign the elements to variables.

(defun bar ()
  (list '((1 . 2) (3 . 4) (5 . 7))
        '((8 . 9) (10 . 23) (30 . 20))))

(destructuring-bind (a b) (bar)
  (format t "~&A: ~s~%B: ~s~%" a b))
; A: ((1 . 2) (3 . 4) (5 . 7))
; B: ((8 . 9) (10 . 23) (30 . 20))
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
jkiiski
  • 8,206
  • 2
  • 28
  • 44
3

If you already have two variables a and b, you can assign the values:

CL-USER 6 > (let ((a 10)
                  (b 3))

              (multiple-value-setq (a b) (truncate a b))

              (list a b))
(3 1)

or alternatively using SETF:

CL-USER 7 > (let ((a 10)
                  (b 3))

              (setf (values a b) (truncate a b))

              (list a b))
(3 1)
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346