Commit 8aa13d07 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

* lisp/emacs-lisp/pcase.el (pcase-lambda): Rewrite.

parent 29f7f98b
2015-03-19 Stefan Monnier <>
* emacs-lisp/pcase.el (pcase-lambda): Rewrite.
* emacs-lisp/eieio.el (object-slots): Return slot names as before
......@@ -166,23 +166,26 @@ like `(,a . ,(pred (< a))) or, with more checks:
(defmacro pcase-lambda (lambda-list &rest body)
"Like `lambda' but allow each argument to be a pattern.
`&rest' argument is supported."
"Like `lambda' but allow each argument to be a UPattern.
I.e. accepts the usual &optional and &rest keywords, but every
formal argument can be any pattern accepted by `pcase' (a mere
variable name being but a special case of it)."
(declare (doc-string 2) (indent defun)
(debug ((&rest pcase-UPAT &optional ["&rest" pcase-UPAT]) body)))
(let ((args (make-symbol "args"))
(pats (mapcar (lambda (u)
(unless (eq u '&rest)
(if (eq (car-safe u) '\`) (cadr u) (list '\, u))))
(body (macroexp-parse-body body)))
;; Handle &rest
(when (eq nil (car (last pats 2)))
(setq pats (append (butlast pats 2) (car (last pats)))))
`(lambda (&rest ,args)
,@(car body)
(pcase ,args
(,(list '\` pats) . ,(cdr body))))))
(debug ((&rest pcase-UPAT) body)))
(let* ((bindings ())
(parsed-body (macroexp-parse-body body))
(args (mapcar (lambda (pat)
(if (symbolp pat)
;; Simple vars and &rest/&optional are just passed
;; through unchanged.
(let ((arg (make-symbol
(format "arg%s" (length bindings)))))
(push `(,pat ,arg) bindings)
`(lambda ,args ,@(car parsed-body)
(pcase-let* ,(nreverse bindings) ,@(cdr parsed-body)))))
(defun pcase--let* (bindings body)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment