2

C-h f backquote:

The whole structure acts as if it were quoted except for certain places where expressions are evaluated and inserted or spliced in.

Vectors work just like lists.

What does the 'spliced in' mean?

;; I expect for (1 2 3)
`(1 ,@[2] 3)  ; => (1 2 3), looks fine

;; I expect for [1 2 3]
`[1 ,@'(2) 3]  ; => [1 2 3], fine too

whereas

`(,@[])   ; => [], what?
`[,@'()]  ; => [(\,@ 'nil)], what's this?
shynur
  • 4,065
  • 1
  • 3
  • 23
  • The weird `\,` also appears in the [question: \`(a \, b) is equivalent to \`(a . ,b)](https://emacs.stackexchange.com/questions/75700) – shynur Jul 09 '23 at 04:00
  • 2
    See `C-h i g (elisp)Backquote` on the meaning of "splice". – phils Jul 09 '23 at 04:10
  • @phils: According to documentation, `(backquote [,@'()])` should return `[]` (?) – shynur Jul 09 '23 at 04:14
  • See my answer, but I suspect the fact that vectors are self-quoting will be the reason for that one. I don't see any documentation which explicitly suggests you could expect to get an empty vector, as all of the examples I can see are list-based. – phils Jul 09 '23 at 04:48

1 Answers1

3

I'm not sure whether or to what extent "Vectors work just like lists" is intended to mean "you can mix and match vectors and lists", but the behaviour does look inconsistent. I suggest you report it as a bug, even if just to clarify the documentation.

`(,@[])   ; => [], what?

You're splicing a vector value into an empty list value, and evidentially the vector "wins" that conflict. Note that the fact that it's an empty vector is not relevant -- when you do this, you just get the vector as a result.

`[,@'()]  ; => [(\,@ 'nil)], what's this?

The \,@ comes from the output of the lisp reader. backquote.el comments:

When the Lisp reader sees `(...), it generates (\` (...)).
When it sees ,... inside such a backquote form, it generates (\, ...).
For ,@... it generates (\,@ ...).

This is also the case outside of a list:

(read ",@foo")
=> (\,@ foo)

And as you'll know, () and nil are the same thing, hence:

(read "[,@'()]")
=> [(\,@ 'nil)]

The question is therefore "why is the verbatim value from the lisp reader ending up in the vector" and I strongly suspect the answer is simply that vectors are self-quoting, and that it's therefore expected behaviour.

Refer to C-hig (elisp)Vectors on this point:

A vector, like a string or a number, is considered a constant for evaluation: the result of evaluating it is the same vector. This does not evaluate or even examine the elements of the vector. *Note Self-Evaluating Forms::

phils
  • 48,657
  • 3
  • 76
  • 115
  • If "*the answer is simply that vectors are self-quoting*" is the reason, why `(backquote [1 ,@'(2) 3])` doesn't return `[1 (\,@ '(2)) 3]`? – shynur Jul 09 '23 at 05:13
  • What does "*the vector 'wins' that conflict*" mean? `(backquote (1 ,@[2]))` even provides a more weird result -- `(1 . [2])`. It doesn't win; it just ends the game. – shynur Jul 09 '23 at 05:17
  • I'm guessing. As I said up front, I suggest that you report this. It might be a bug or it might just be undefined behaviour. – phils Jul 09 '23 at 05:22
  • 1
    "*I suggest that you report this.*" -- +1; will do. – shynur Jul 09 '23 at 05:25