emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

question about "" and printing circular structure


From: Drew Adams
Subject: question about "" and printing circular structure
Date: Sat, 29 Sep 2012 14:34:32 -0700

(setq x "")

1.
(setq g (list x x))
(let ((print-circle t)) (pp g))

2.
(setq h (list x (copy-sequence x)))
(let ((print-circle t)) (pp h))

#1 prints (#1="" #1#) for g, which is what I would expect, IF there can be more
than one "" object.  This syntax specifically calls out that the two elements of
the list are `eq'.  Why?  Presumably because not all "" strings are created
equal (`eq').

In Emacs 22, #2 prints ("" "") for h, which seems correct to me.  But in Emacs
23-24, #2 prints the same thing for g and h: (#1="" #1#).

("" "") is what I'd expect if there can be more than one "" object.  And in
Emacs 22, (eq (car h) (cadr h)) does in fact return nil.

In Emacs 23-24, however, (eq (car h) (cadr h)) returns t.  So it makes sense
that g and h print the same thing.  What does not make sense, to me, is that
what they print is (#1="" #1#) and not ("" "").

If there is only ever one "" object then I would not expect circular-struture
syntax to be employed at all for it.  Why isn't ("" "") printed, it being
understood that "" and "" are ALWAYS `eq'?

Compare the handling of "" and ().  There is only one () object.  Consequently
neither `print-circle' nor the Lisp reader fiddle with circular structure syntax
when () is involved.

Of course not.  Why would they? () is ALWAYS `eq' to ().  Circular-structure
syntax makes sense only when there is some other possibility, i.e., if "" and ""
are sometimes NOT `eq'.

For the above examples, but with () in place of "", the printed result is always
(() ()), even though it is true that the car and cadr of that list are `eq'.  We
never print (#1=() #1#).

That is what I would expect too, because there is only one () object.  We
understand that, and so do the Lisp writer (`print-circle') and reader (duh).

So why do the writer and reader still use circular-struture syntax for "", now
that there is only one empty-string object?

It seems to me that for "" one of two things should be true:

a. There is only one "" object, AND `print-circle' and `read' treat it as just
"".  They do not mess around using circular structure syntax for it.  They
understand it the same way we do.  They treat it the same way they treat ().

b. There can be multiple "" objects (not `eq'), AND the print/read behavior is
as it was back in Emacs 22: `copy-sequence' returns a new such object - i.e., it
does not share structure with the original.  "" behaves the same way as [] in
this case.

If there is only one "" object, as it now seems, why does `print-circle' print
it using circular-structure syntax?  Can't the Emacs Lisp reader DTRT when it
encounters ""?

Seems like a bug, to me.  Seems like someone decided for Emacs to have only one
empty-list object, but did not bother to let `print-circle' and `read' know
about it.  Seems like they should be let in on the secret now.

Am I missing something?

BTW, I think the doc for `copy-sequence' should make clear that a new sequence
is not returned if the sequence is an empty list or empty string.

As for vectors, it seems that [] is now the odd man out.  There can be multiple
[], which are not `eq'.  As long as that is the case, the way [] is handled by
`print-circle' and `read' is correct.  It is handled the same way we used to
handle "" (in Emacs 22).  The only bug I see at present is the print/read
handling of "".

(But why is [] not in line with the others?)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]