¿Es posible asignar múltiples valores de retorno directamente a las variables sin pasar por una variable temporal en Emacs Lisp?
Por ejemplo, supongamos que tengo una función que devuelve una lista de dos listas:
(defun test-func ()
  (setq a '(a b))
  (setq b '(c d))
  `(,a ,b))
Si quiero asignar el primer valor de retorno a list-ay el segundo valor de retorno a list-b, puedo hacer esto usando una variable temporal temp, por ejemplo:
(let* ((temp (test-func)) (list-a (car temp)) (list-b (cadr temp)))
  (message-box (prin1-to-string list-a))
  (message-box (prin1-to-string list-b)))
¿Es posible hacer esto de manera más simple? (Estoy acostumbrado a Perl y Python donde no tienes que especificar una variable temporal)
                    
                        let-binding
                                
                    
                    
                        Håkon Hægland
fuente
                
                fuente

cl-destructuring-bindmacro. Además, ¿realmente pretendías usarsetqdentro de adefun?setqcrea una variable "especial" (accesible a nivel mundial), algo que normalmente pondría fuera de una función (porque tiene poco significado declarar la misma variable más de una vez, mientras que las funciones deben ejecutarse más de una vez).letdentro de la función. No tenía planeado establecer ninguna variable global :)Respuestas:
Common Lisp tiene una instalación especial: múltiples valores , y la biblioteca de compatibilidad Emacs Lisp los emula usando listas .
Así puedes hacer
(Cargue
cl-liby use elcl-prefijo para toda la funcionalidad CL en EL).NB : si mira la respuesta SO vinculada anteriormente, verá que emular MV con listas es, por decirlo suavemente, subóptimo (vea también el comentario de @ Stefan a continuación).
fuente
multiple-value-bindlugar decl-multiple-value-bind(solo este último parece estar documentado en el manual gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?clpaquete ya no está destinado a ser utilizado. Siempre debe usar elcl-libpaquete, que define las funciones con elcl-prefijo ..cl-values: es una emulación de "mejor esfuerzo" de CommonLisp,valuespero no es realmente compatible, ya que todo lo que hace es devolver una lista (es decir, es una mentira), y en mi experiencia la gente tarde o temprano termina manipulando esos como listas (es decir, rompiendo la abstracción): mejor use las listas explícitamente (y si no le gustapcase-let, entonces use encl-destructuring-bindlugar decl-multiple-value-bind).Además de confiar en el
cl-libpaquete de compatibilidad, la forma recomendada en Elisp es usarpcase:Al lado
pcase-let, también haypcase-dolist,pcase-lambdaypcaseen sí.fuente