Create a list that contains T as single element
Asked Answered
S

1

7

I have come across a problem where I'm not sure whether I got everything right I learned so far on Lisp.

Basically the task is trivial: Create a list that contains only a single item - the T literal.

My first approach was:

'(t)

Is this correct? Basically, it evaluates to

(T)

which seems to be correct. As the symbol T evaluates to itself, this should do the job. But then it got me thinking… If I write

'(s)

I get:

(S)

This looks pretty much the same, but should evaluate in a different way. So I thought about

(list t)

which also results in:

(T)

If I compare the symbols using eq they are equal:

(eq (car (list t)) (car '(t)))

And also if I I compare both values to T directly, everything is fine:

(eq (car (list t)) t)
(eq (car '(t)) t)

So, to cut a long story short: '(t) does the job, doesn't it?

Selle answered 15/4, 2015 at 7:40 Comment(0)
A
8

I don't think you understand evaluation fully.

We now look at Lisp code. That means source code of a programming language. Not s-expressions:

'(t)

Above is the same as:

(quote (t))

If we evaluate it, Lisp sees the QUOTE special operator. QUOTE prevents evaluation of the enclosed form and returns it.

Thus the result is (T). T never gets evaluated. (T) never gets evaluated. (T) is a constant literal list.

If you write '(s) or '(sin) or whatever other symbol, it does not matter. It is always a constant literal list of one symbol.

Code again:

(list t)

That's a function application. When evaluated:

  • Lisp sees a list with LIST as a function.

  • it evaluates the arguments. T is evaluated to itself.

  • it calls LIST with the argument T.

  • the function LIST returns a fresh list: (T).

What is the difference between

(defun foo ()
  '(t))

and

(defun bar ()
  (list t))

?

FOO returns a constant literal list, embedded in the code.

BAR calls LIST at runtime and each time it returns a fresh list.

Both lists contain the same symbol: T.

So the difference boils down to constant data vs. data created by a function.

Autumnautumnal answered 15/4, 2015 at 7:49 Comment(5)
Great explanation, thanks :-). I still too often don't think about what quoting means … apart from that, the hint with constant data vs data created by a function is quite helpful. Thanks!Selle
Quoting means that exactly the thing returned by the reader is used.Voucher
@Svante: Not generally in Common Lisp. Under file compilation there are cases where this is not the case for literal objects. For example you have source code which uses two lists (1 2 3). The lists can be EQ or not. In one case the reader might read something, which does not end up in the code. Also imagine, the reader runs in one Lisp where the code is compiled and another Lisp into which the compiled code gets loaded.Autumnautumnal
@RainerJoswig: Indeed an excellent explanation. There is one thing I'd like to point out, though. Your foo example does not return a constant. This is a trap beginners get caught a great deal. Try this: (defun foo () '(t)) (nconc (foo) '(a b c)) (foo)Wearproof
@andwagon: it's conceptually a constant. The effects on changing it are undefined. In the standard. it could be in some read-only memory, it could cause an error to be signaled, it could be ignored, it could be shared in several places, ... Since it is undefined what happens, it makes no sense to actually change it in portable code...Autumnautumnal

© 2022 - 2024 — McMap. All rights reserved.