5

I noticed both pcase-let and cl-destructuring-bind seem to perform the same operation.

Is there any difference or reason to use one instead of the other?

eg:

(pcase-let ((`(,filename ,buf) (pop filename-and-buffer-list)))
  ;; do stuff.
  )

Seems to behave the same as:

(cl-destructuring-bind (filename buf) (pop filename-and-buffer-list)
  ;; do stuff.
  )
2
  • 3
    Nothing more than personal preference, IMO. destructuring-bind has been around much longer than pcase, and personally I find pcase forms harder to read; but YMMV. I'd just say use whichever one you like best.
    – phils
    Commented Dec 21, 2019 at 14:09
  • What @phils said. (And cl-destructuring-bind is a Common Lisp emulation, as you probably know.)
    – Drew
    Commented Dec 21, 2019 at 15:17

1 Answer 1

10

cl-destructuring-bind was designed more or less specifically to destructure data made of cons cells. pcase-let on the other hand is just a special case of pcase which was designed to handle arbitrary data and be extensible (and be able to discriminate rather than only destructure).

So cl-destructuring-bind has a slightly more concise syntax for the simple cases like the one you show, whereas pcase-let imposes a more verbose syntax in exchange for the ability to destructure other data types such as structs, hash-tables, ...

Another difference is that pcase-let allows you to perform several such bindings, as in

(pcase-let ((PAT1 EXP1)
            (PAT2 EXP2)
            ...)
  ..)

whereas cl-destructuring-bind focuses on the single-pattern case, so you'd have to use

(cl-destructuring-bind PAT1 EXP1
  (cl-destructuring-bind PAT2 EXP2
    ...))

which again makes cl-destructuring-bind less verbose in the simple case.

As the designer&implementer of pcase I consider that the added verbosity cost of pcase-lets generality is minor (compared to the advantage of having a single syntax of patterns that works both for simple and complex cases).

4
  • The docs for pcase-let states: The precise behavior when the object does not actually match the pattern is undefined, although the body will not be silently skipped: either an error is signaled or the body is run with some of the variables potentially bound to arbitrary values like nil. Are there any recommendations for how to use pcase-let in order to avoid encountering this undefined behavior? Preferably the pattern either matches and the binding succeeds or an error is reported. In other words, how to avoid a silent fail on the pattern match? Commented Apr 17 at 4:27
  • Use pcase or pcase-exhaustive?
    – Stefan
    Commented Apr 18 at 13:24
  • Can you elaborate with a simple example on how you would rewrite a typical use-case for pcase-let using pcase to avoid a silent fail? A more thorough explanation for how to use pcase-exhaustive and how it differs from pcase would also be helpful (cf. doc string for pcase-exhaustive ) Commented Apr 27 at 1:56
  • Please open a bug report if you think the doc is not sufficient. Emacs users shouldn't need to lookup stackexchange to know how to use pcase.
    – Stefan
    Commented Apr 28 at 3:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.