Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of @ (at-sign) in Lisp?

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 @.

like image 835
ApproachingDarknessFish Avatar asked Jan 30 '14 17:01

ApproachingDarknessFish


People also ask

What are symbols in LISP?

A Lisp symbol is a data object that has three user-visible components: The property list is a list that effectively provides each symbol with many modifiable named components. The print name must be a string, which is the sequence of characters used to identify the symbol.

What is meant by symbolic representation in LISP?

LISP expressions are called symbolic expressions or s-expressions. The s-expressions are composed of three valid objects, atoms, lists and strings. Any s-expression is a valid program. LISP programs run either on an interpreter or as compiled code.

What is #' used in LISP?

#'functionname in Common Lisp Above defines a local variable FOO and a local function FOO . The list statement returns the value of FOO , then the function value of foo using the (function ...) notation, then the same using the short hand notation and then the value of actually calling the function FOO .

What are the different properties of LISP?

In Lisp, every symbol has a property list (plist). When a symbol is created initially its property list is empty. A property list consists of entries where every entry consists of a key called an indicator and a value called a property . There are no duplicates among the indicators.


2 Answers

“,@” 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.

like image 152
Joshua Taylor Avatar answered Nov 11 '22 07:11

Joshua Taylor


,@ 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.

like image 21
6502 Avatar answered Nov 11 '22 07:11

6502