Subject: Re: bug#67455: (Record source position, etc., in doc strings, and use this in *Help* and backtraces.)

From: Stefan Monnier <[email-masked]>
Date: Mon, 08 Apr 2024 08:00:34 -0400

>> How?  `macroexp--expand-all` will not be passed this `lambda` because
>> it's not an *expression*.
> Well, when I commented out that pcase arm, the lambda no longer got
> stripped.  I'm not sure what you mean by expression.

In Edebug specs we call it `form`.

The ((x 3) (y 4)) in a `let` is not an expression, for example.
(4 . 5) could appear in a piece of code in the position where we expect
an expression but it is not a valid expression (it will result in a syntax
error at compile- or run-time).

The grammar of ELisp is made of various elements, one of which would
traditionally be called "expressions".  If we could specify it in EBNF
it could look something like the following:

    <formalargs> ::= "(" <id>* [ "&optional" <id>* [ "&rest" <id> ]] ")"
    <decls> ::= "(" <decl>* ")"
    <decl> ::= <id> | "(" <id> <exp> ")"
    <func> ::= <id> | "(" "lambda" <formalargs> <exp>* ")"
    ...
    <exp> ::= <id>
            | "(" <func> <exp>* ")"
            | "(" "quote" <sexp> ")"
            | "(" "let" <decls> <exp>* ")"
            | "(" "function" <func> ")"
            | ...

Only the <exp> parts go through `macroexp--expand-all`.

        Stefan