Optional characters in Common Lisp

Several times I came across the concept of uninterrupted characters, but I do not quite understand what it is.

Is there a way to put a character created using (character-to-character)?
Is it possible to assign a value to a symbol without interning it?
Is it possible to rename a character (interned or uninterned)?
What else can you do with a character without a character?

Update:
What happens to characters in this piece of code?

CL-USER> (defun func () (let ((var 'sym)) (print (find-symbol "sym")) (print var))) FUNC CL-USER> (func) NIL SYM SYM 

My misunderstanding:
1. find-symbol prints zero, so the character is not overloaded
2. var prints sym without #: at the beginning, which means it's interned

+7
source share
2 answers

Non-determinate characters are mainly used as names or pointers to avoid cluttering packages or for related tasks.

For example:

 T1> (find-symbol "T2") NIL NIL T1> (find-symbol "T3") NIL NIL T1> (defpackage t2) #<Package "T2"> T1> (defpackage #:t3) #<Package "T3"> T1> (find-symbol "T2") T2 :INTERNAL T1> (find-symbol "T3") NIL NIL 

As you can see, using t2 in the first form of defpackage puts it in package t1 , and when using #:t3 in the second defpackage avoids this. This is possible because defpackage accepts a string pointer as its first element, and the character does not need to be interned to work as a pointer.

These and related situations are that uninterrupted characters are mainly used intentionally. You can also avoid polluting the package by using a string or keyword, but in the first case there may be problems with people using non-standard reading files, and in the second case you will pollute the keyword package, which some people care about. (There are different opinions as to whether this is really so bad or not.)

Then there are situations when a symbol loses its home package (for example, unintern ing) and becomes at least, apparently, non-Internet. (It can still be interned in a different package.)

 T1> (defparameter *t2* (find-symbol "T2")) *T2* T1> (import *t2* "T3") T T1> (symbol-package *t2*) #<Package "T1"> T1> (unintern *t2*) T T1> (find-symbol "T2") NIL NIL T1> (symbol-package *t2*) NIL T1> *t2* #:T2 T1> (find-symbol "T2" "T3") #:T2 :INTERNAL T1> (unintern *t2* "T3") T T1> (import *t2* "T3") T T1> *t2* T3::T2 T1> (symbol-package *t2*) #<Package "T3"> 

So the answer to

Is there a way to put a character created using (make-symbol)?

: yes:

 T1> (import (make-symbol "T4")) T T1> (find-symbol "T4") T4 :INTERNAL 

Is it possible to assign a value to a symbol without interning it?

Yes, when you lose a property that can be uniquely identified by its name and packaging, you can still use its value slot, plist, etc.:

 T1> (let ((symbol '#:t5)) (setf (symbol-value symbol) 1) (setf (get symbol :foo) :bar) (setf (symbol-function symbol) (lambda ())) (values (symbol-value symbol) (get symbol :foo) (symbol-function symbol))) 1 :BAR #<Anonymous Function #xC829036> 

Is it possible to rename a symbol (internally or uninterrupted)?

The consequences of changing the symbol name are undefined.

What else can you do with a character without a character?

I really think that they are mainly used as pointers in package definitions, but for a general answer it would be: they can be useful in situations where you want to name things without using hard-coded strings and don't want to foul any package.

+8
source
  • Yes

     CL-USER> (intern (string (make-symbol "TEST"))) TEST :INTERNAL 
  • Not

  • Not

  • It is usually used in a package declaration so as not to pollute the namespace of the package in which the declaration takes place (if a regular character is used) or the keyword package, since the entries in defpackage form :export and :use are converted to a string anyway. That way you can use it in functions that take anything and convert them to strings. More generally, uninterrupted characters can be used as unique objects with a name and nothing else. But usually keywords are used for this purpose.

+1
source

All Articles