Jiminion
Jiminion

Reputation: 5168

Why does single quote in Lisp always return upper case?

I'd like to be able to set case from a single quote, but that does not seem possible.

(format nil "The value is: ~a" 'foo)
"The value is: FOO"

(format nil "The value is: ~a" 'FOO)
"The value is: FOO"

(format nil "The value is: ~a" "Foo")
"The value is: Foo"

Upvotes: 4

Views: 1699

Answers (5)

Frank Zalkow
Frank Zalkow

Reputation: 3930

For understanding what's going on, see Rainer Joswigs answer. Just one thing to add: You can control the case of a printed symbol (without vertical bar syntax) with *print-case*:

CL-USER 1 > (let ((*print-case* :downcase))
              (format nil "The value is: ~a" 'foo))
"The value is: foo"

CL-USER 2 > (let ((*print-case* :capitalize))
              (format nil "The value is: ~a" 'foo))
"The value is: Foo"

CL-USER 3 > (let ((*print-case* :upcase)) ; default
              (format nil "The value is: ~a" 'foo))
"The value is: FOO"

Upvotes: 0

Vatine
Vatine

Reputation: 21258

'foo means "suppress the evaluation of the symbol FOO, leaving only the symbol FOO". Common Lisp tends towards upcasing symbol names by default (so the symbols expressed as 'foo, 'Foo and 'FOO are all the same symbol, with the symbol name "FOO").

To see exactly what your implementation will do, you can check the readtable case of the current readtable see CLHS, ch 23.1.2, effect of readtable case by calling (readtabe-case *readtable*).

Some lisp implementations will start with the readtable-case as :preserve.

As for if you should use symbols or strings, it's one of those "it depends". If you're not worried about cse preservation, using interned symbols gives you less storage and quicker comparison, at the (possible) price of case-mangling. But if case is important, the balance is probably further towards the "use strings throughout" end of the scale.

Upvotes: 1

Jiminion
Jiminion

Reputation: 5168

OK, this works:

(format nil "The value is: ~a" (string-downcase 'foo))
"The value is: foo"

Even better (from Rainer)

 (format nil "The value is: ~(~a~)" 'foo)

I am still thinking one shouldn't use 'foo instead of "foo" if the intent is to represent a string.

Upvotes: -1

Rainer Joswig
Rainer Joswig

Reputation: 139251

Quoting

The quote has nothing to do with case. A quote prevents evaluation.

quoting a symbol:

CL-USER 1 > 'foo
FOO

quoting a list:

CL-USER 2 > '(1 2 3 foo)
(1 2 3 FOO)

You can put a quote in front of many things. For example in front of a string:

CL-USER 3 > '"a b c"
"a b c"

Since strings evaluate to themselves, quoting them or not makes no difference:

CL-USER 4 > "a b c"
"a b c"

Symbols are by default read as uppercase:

CL-USER 5 > 'FooBar
FOOBAR

CL-USER 6 > (symbol-name 'FooBar)
"FOOBAR"

But that has nothing to do with quoting and is a feature of the reader.

CL-USER 7 > (read-from-string "foo")
FOO
3

Downcase

If you want the string in lowercase, you need to convert the string to lowercase:

CL-USER 8 > (string-downcase (symbol-name 'FooBar))
"foobar"

Symbols with mixed case

But you can create symbols with lowercase names or mixed case. You need to escape them:

CL-USER 9 > '|This is a symbol With spaces and mixed case|
|This is a symbol With spaces and mixed case|

CL-USER 10 > 'F\o\oB\a\r
|FooBar|

Downcasing output using FORMAT

You can also tell FORMAT to print in lowercase:

CL-USER 11 > (format nil "The value is: ~(~a~)" 'foo) 
"The value is: foo"

Upvotes: 13

Tordek
Tordek

Reputation: 10872

Lisp symbols, like 'a, are case insensitive. You can check that by doing...

(eq 'a 'A)

They are the same symbol.

If you need to differentiate case, you should use strings or characters, as appropriate.

In order to make format print symbols in a particular case, you can set the *print-case* global variable to :upcase, :downcase or :capitalize depending on your needs.

Upvotes: 0

Related Questions