Lisp (or at least Common Lisp) does have a very well defined `true` boolean type.
* (typep t 'boolean) => t
* (typep nil 'boolean) => t
* (typep 3 'boolean) => nil
The fact that t an nil are also symbols (and nil the empty list) is irrelevant.
As for the character issue the idea is a nice one and works well for graphic characters but issues start arising when you look outside that particular set to characters like #\Null, #\Return and #\Newline.
Even more hairy are when you want to represent characters like #\Control-\x or #\Meta-\m (not portable btw) which have no reasonable representation as a single character string.
Personally I'm all for a distinct data type which allows extra information to be attached to it but within a language which uniformly allows singleton strings to designate characters and vice-versa.
The CL boolean type is kind of how I'd like characters to work. Characters would be characters, but they'd also be length one strings, same as how T is a boolean, but it's also a symbol.
I agree that special characters require a different representation (using "\n" and so on all the time is not nice). Perhaps though they could still be strings, but just written with a different syntax?
Yep. As '() () and nil are equivalent, maybe #\x and "x" should be equivalent too (and so that would work with #\null too : it is the only way to read it (I think), but it is used as a 1-char-long string.
(defun copy-instance (i)
(loop with i-class = (class-of i)
with c = (allocate-instance i-class)
for sd in (mop:class-slots i-class)
for sn = (mop:slot-definition-name sd)
when (slot-boundp i sn)
do (setf (slot-value c sn)
(slot-value i sn))
finally (return c)))
But what if necessary side-effects happen in initialize-instance? Though that could as easily make a case for allocate-instance, if Paul needs to avoid those side effects.
I think the bottom line is that I should have emphasized that copy-instance above might not survive first contact with the enemy (the functional requirements).