Meaning of @ (at-sign) in Lisp?
Asked Answered
B

3

21

You all know the story: programmer reads other people's code, programmer sees symbol they don't understand, Google fails them because it's difficult to search for non-alphanumeric symbols.

This time it's the @ symbol, which seems to be used to inject the contents of one list into the middle of another. For instance:

`(5 6 7 ,@'(8 9) 10 11)
;=> (5 6 7 8 9 10 11)

I'm comfortable with this usage, but I'm wondering whether I understand the behavior of @ correctly? Does it have other uses? And what causes the error in the following transcript (from CLISP)?

[1]> (list 1 2 3 4 @'(5 6 7))

*** - SYSTEM::READ-EVAL-PRINT: variable @ has no value

Lastly, what exactly is @? It doesn't seem to be a function:

[3]> (print #'@)

*** - FUNCTION: undefined function @

I'm guessing it's a fundamental syntax like the backquote (`), or comma (,). Is this correct? Sorry if this is a duplicate, but once again, as far as I know it's impossible to search for @.

Balboa answered 30/1, 2014 at 17:52 Comment(3)
this might be useful..Lanate
@MikeChristensen That confirms my hypothesis concerning what it does, but I'd still like some additional explanations.Balboa
I found that you can actually get reasonable Google results by spelling out what the character is. For example, Google Lisp "at sign".Conversationalist
B
20

“,@” is used to splice within backquotes…

It's described in the HyperSpec in the section on backquote:

2.4.6 Backquote

If a comma is immediately followed by an at-sign, then the form following the at-sign is evaluated to produce a list of objects. These objects are then “spliced” into place in the template. For example, if x has the value (a b c), then

 `(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x))
=>  (x (a b c) a b c foo b bar (b c) baz b c)

It's worth noting that ,@ isn't always necessary; according to the same documentation:

Anywhere “,@” may be used, the syntax “,.” may be used instead to indicate that it is permissible to operate destructively on the list structure produced by the form following the “,.” (in effect, to use nconc instead of append).

…but “@” on its own is just another letter…

Your intuition is mostly correct when you ask, "so basically @ on its own means nothing and the only real operator is ,@?" @ can be used in other places as a normal letter. That's why you get the error that you mentioned: (list 1 2 3 4 @'(5 6 7)) is simply

(list 1 2 3 4 @ '(5 6 7))

and @ is a variable, but it doesn't have a value here. Compare that with:

(let ((@ 4.5))
  (list 1 2 3 4 @ '(5 6 7)))
;=> (1 2 3 4 4.5 (5 6 7))

…that can, unfortunately, be hard to search for.

Sorry if this is a duplicate, but once again, as far as I know it's impossible to search for "@".

Searching for documentation on certain non-alphanumeric characters can be difficult, but I've found a few techniques that can help. E.g., if you go to lispdoc.com, you can search for comma, and the results there will get you headed toward backquote. (Searching for at-sign didn't help though.) That's not a perfect solution, but it can help sometimes.

Beora answered 30/1, 2014 at 18:35 Comment(0)
B
6

,@ should be considered a single entity, and the meaning of ,@ is that the following expressions is spliced into the current quasi-quoted list.

For example you cannot use

`,@x

because the quasi-quoted expression is not a list and ,@ requires a list to be spliced to. Similarly (in my reading of the standard) you cannot use

`(list ,@5)

because 5 is not a list (however both SBCL and CLISP allow it and expand to (list . 5)).

EDIT

Actually the behavior of SBCL and CLISP is acceptable, but it would also be acceptable for a compliant implementation to give an error if ,@ is used with a non-list argument.

CLHS section 2.4.6 last possible expansion for `((,a b) ,c ,@d) shows that raising an error for a non-list could be acceptable too.

Bulldoze answered 30/1, 2014 at 18:36 Comment(1)
Nice note about the behavior of `,@X where X isn't a list!Beora
B
1

Comma-at is for list splicing in CL. It places the list content into the expression containing it, removing the list's outermost parantheses. Paul Graham's now freely available book "On Lisp" contains many more details about it, if my mind serves me right, and is a good read anyway if you want to learn more about advanced Lisp.

Borszcz answered 30/1, 2014 at 18:23 Comment(1)
So basically @ on its own means nothing and the only real operator is ,@?Balboa

© 2022 - 2024 — McMap. All rights reserved.