Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
An alternate pattern-matching conditional for Elisp (lwn.net)
86 points by signa11 on March 15, 2024 | hide | past | favorite | 14 comments


Looking at the pcase structure with some basic emacs-lisp experience (OK, slightly better than basic, but I'm still sloppy), I find it really easy to grock having never seen it before.

They mention repurposing the comma and backtick to serve functions that they don't elsewhere, which I agree is probably worth changing, but otherwise I can't understand at all what the issue is. And reading about the problems with cond*, it seems worse to me in every way. Not terrible, but certainly worse.

I don't really understand why Stallman considers cond* better even by the standards of his own arguments. Very odd, I feel I must be missing something.

Maybe if I tried to use it the issues would become evident.


You can't employ backquote in pattern matching syntax usefully without giving semantics it doesn't have elsewhere. If `(a b ,c) means match a list in which a and b are literals, and the third item is unified with our variable c, then backquote is doing something it doesn't do elsewhere (which is conceptually related to what it does elsewhere).


I'd drop the weirdly named operators like cdr-safe, or change the naming at least.

I get that if you're manually writing code to match a list structure, you do it in a "cdr safe" way. E.g. if we are matching a two element object, we can't assume that it has an accessible cadr.

It's the job of pattern matching to do the shape checks so as not to misuse the object being matched; no aspect of that needs to be visible, including naming like "cdr safe".



I am not familiar with `pcase` in Elisp, but `case` is a perennial favorite in languages like Elixir and Lisp Flavored Erlang. I hope `cond*` doesn’t deviate too far from this norm.


Ironically, there are opportunities to make the implementation of cond* nicer using pcase, like the big switch in the cond*-subpat function.

cond* could also be written in itself. One way would be to have a minimal bootstrapping cond* which handles just that subset of the syntax which is used in the implementation of the real, production cond*.


`cond*` reads more like `do` notation in Haskell than `match`.


> (...) there would be no effort to switch away from pcase, however, as it is "to be considered a matter of stylistic preference".

I'm sometimes glad that the CL standard is frozen.

Sarcasm aside, this is literally https://xkcd.com/927/.

Sarcasm aside for real this time, getting this sort of binding mechanism in a COND-like form is unusual. This effectively means that a programmer needs to inspect all previous COND* forms, instead of relying on lexical scope AND indentation as they normally would, to see where new bindings are made. This is like Common Lisp's LOOP, but even there bindings are only allowed at the beginning of the loop, before any iteration clauses.


I think you need to go down the conditionals in order anyway, if cond* it’s like cond in that it evaluates the conditions top to bottom. So keeping track of “all the bindings so far” makes intuitive sense to me.

I also see a parallel to if/else if/else cascades. You can “break” and else if leg into … else { zzz; if (…) … } and then you can declare new variables at the zzz spot that are then available for the rest of the cascade.

I don’t know much about pcase and cond* so I can’t speak to the more general point. I just wanted to mention one specific aspect.

I miss emacs but as a Java developer what can you do…


Evaluating conditions don't introduce bindings in COND. In Lisp typically bindings are only introduced in forms together with scope: DEFUN, LET, and a lot of other constructs. Binding construct which affect forms outside its syntactic scope is rare in Lisp.

In Scheme there is sometimes:

    (define (foo)
      (define a 10)
      (+ a 42))
But even there all the embedded "define"s, by standard, need to be at the top of the body, directly at the start.


It may be unusual, but binding is the point of pattern matching. Expressions take a bunch of bindings and give a value; patterns take a value and give a bunch of bindings.


Scope of the bindings is the problem, not the bindings itself.


I had assumed bindings would be scoped to their branch; if they leak, yeah, definitely problematic.


Agree, it is Curse of Lisp mixed in NIH syndrome. Syntax of cond* is no more straightforward than that of pcase. As was pointed out on mailing list. Awkward decision by maintainers to keep both into core.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: