GNU bug report logs - #55395
What does (1 2 3 . #2) mean?

Previous Next

Package: emacs;

Reported by: Mattias Engdegård <mattiase <at> acm.org>

Date: Fri, 13 May 2022 11:41:01 UTC

Severity: normal

To reply to this bug, email your comments to 55395 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 11:41:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Mattias Engdegård <mattiase <at> acm.org>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 13 May 2022 11:41:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: bug-gnu-emacs <at> gnu.org
Subject: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 13:32:34 +0200
What, exactly, does the #N print notation mean (with print-circle=nil)?

Let's define (rho LEAD LOOP) as the iota list that has a loop LOOP long after LEAD initial elements:

(defun rho (lead loop)
  (let ((l (number-sequence 1 (+ lead loop))))
    (setcdr (nthcdr (+ lead loop -1) l) (nthcdr lead l))
    l))

Then we have:

(rho 0 1) => (1 . #0)
(rho 0 2) => (1 2 1 2 . #2)
(rho 0 3) => (1 2 3 1 2 . #2)
(rho 0 4) => (1 2 3 4 1 2 3 4 1 2 . #5)
(rho 0 5) => (1 2 3 4 5 1 2 3 4 5 1 . #5)
(rho 1 4) => (1 2 3 4 5 2 3 4 5 2 . #5)
(rho 4 1) => (1 2 3 4 5 5 5 . #3)

and so on. The pattern is not obvious to me.

It may have made more sense before the switch of cycle-detection algorithm from Floyd to Brent. This can be fixed by hand-coding the list iteration and explicitly remembering the index of the tortoise, but would that be correct? What's the spec?

If #N means 'Nth object from the top along the path to the current object, starting at 0' then we should have

(rho 2 3) => (1 2 3 4 5 . #2)
(list (rho 2 3)) => ((1 2 3 4 5 . #3))

ie, adding the print depth to the index in the list. Do you agree?





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 15:23:02 GMT) Full text and rfc822 format available.

Message #8 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 55395 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 17:22:13 +0200
Mattias Engdegård <mattiase <at> acm.org> writes:

> It may have made more sense before the switch of cycle-detection algorithm from Floyd to Brent. This can be fixed by hand-coding the list iteration and explicitly remembering the index of the tortoise, but would that be correct? What's the spec?

I don't think I've ever considered #x to be meaningful outside of
print-circle, but I guess if we wanted to have some semantics here, I
think I would have expected the index of the tortoise?  But...

> If #N means 'Nth object from the top along the path to the current object, starting at 0' then we should have
>
> (rho 2 3) => (1 2 3 4 5 . #2)
> (list (rho 2 3)) => ((1 2 3 4 5 . #3))
>
> ie, adding the print depth to the index in the list. Do you agree?

I've added Stefan to the CCs; I'm sure he has an opinion.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 16:09:01 GMT) Full text and rfc822 format available.

Message #11 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Andreas Schwab <schwab <at> linux-m68k.org>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 55395 <at> debbugs.gnu.org
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 18:08:33 +0200
On Mai 13 2022, Mattias Engdegård wrote:

> Let's define (rho LEAD LOOP) as the iota list that has a loop LOOP long after LEAD initial elements:
>
> (defun rho (lead loop)
>   (let ((l (number-sequence 1 (+ lead loop))))
>     (setcdr (nthcdr (+ lead loop -1) l) (nthcdr lead l))
>     l))
>
> Then we have:
>
> (rho 0 1) => (1 . #0)
> (rho 0 2) => (1 2 1 2 . #2)
> (rho 0 3) => (1 2 3 1 2 . #2)
> (rho 0 4) => (1 2 3 4 1 2 3 4 1 2 . #5)
> (rho 0 5) => (1 2 3 4 5 1 2 3 4 5 1 . #5)
> (rho 1 4) => (1 2 3 4 5 2 3 4 5 2 . #5)
> (rho 4 1) => (1 2 3 4 5 5 5 . #3)
>
> and so on. The pattern is not obvious to me.
>
> It may have made more sense before the switch of cycle-detection algorithm from Floyd to Brent. This can be fixed by hand-coding the list iteration and explicitly remembering the index of the tortoise, but would that be correct? What's the spec?

I don't think there is a defined meaning behind the number, it's more an
implementation detail.  If you want to have precise cycle detection you
need to enable print-circle.

-- 
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 17:22:02 GMT) Full text and rfc822 format available.

Message #14 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: 55395 <at> debbugs.gnu.org,
 Mattias Engdegård <mattiase <at> acm.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 13:20:51 -0400
>> It may have made more sense before the switch of cycle-detection algorithm
>> from Floyd to Brent. This can be fixed by hand-coding the list iteration
>> and explicitly remembering the index of the tortoise, but would that be
>> correct? What's the spec?
>
> I don't think I've ever considered #x to be meaningful outside of
> print-circle, but I guess if we wanted to have some semantics here, I
> think I would have expected the index of the tortoise?  But...

Agreed (and agreed with Andreas as well).
The main goal is to avoid inf-looping and the #NNN chosen is
somewhat arbitrary.

I don't think it's worth it to try and make those #NNN more precise.
If the arbitrariness of the specific #NNN chosen is a problem, we could
replace it with a fixed `#¡cycle!` or something like that (or if we
want it to be more user-readable we could print something like
#cycle:<OBJ> where OBJ is the first N layers of the rest of the cycle,
like (rho 0 2) => (1 2 1 2 . #cycle:(1 2 1 ...))

I'm personally more bothered by the fact that those #NNN use exactly the
same syntax as used with `print-circle` yet they don't have the
same semantics.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 19:55:01 GMT) Full text and rfc822 format available.

Message #17 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 55395 <at> debbugs.gnu.org,
 Mattias Engdegård <mattiase <at> acm.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 21:54:30 +0200
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Agreed (and agreed with Andreas as well).
> The main goal is to avoid inf-looping and the #NNN chosen is
> somewhat arbitrary.
>
> I don't think it's worth it to try and make those #NNN more precise.

So it seems like everybody basically agrees on that...  so if Mattias
wants to implement something here to give them some semantics, he can
pretty much choose whatever he wants?

Or just document that there's really no semantics here without
print-circle, if he prefers.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Fri, 13 May 2022 20:02:01 GMT) Full text and rfc822 format available.

Message #20 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 55395 <at> debbugs.gnu.org, Lars Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Fri, 13 May 2022 22:01:44 +0200
13 maj 2022 kl. 19.20 skrev Stefan Monnier <monnier <at> iro.umontreal.ca>:

> The main goal is to avoid inf-looping and the #NNN chosen is
> somewhat arbitrary.

It seems to have sort-of worked before and was broken, inadvertently and with the best intentions, by a later change.

Additionally the #N value appears to be correct for other object types. For example,

  [a [b #1=[[c #1# d]]]]

is printed as

  [a [b [[c #2 d]]]]

which is consistent with the manual.

> I don't think it's worth it to try and make those #NNN more precise.

I have a simple patch but it is not based on master so it will have to wait.

> I'm personally more bothered by the fact that those #NNN use exactly the
> same syntax as used with `print-circle` yet they don't have the
> same semantics.

The syntax isn't exactly the same (#N vs #N= and #N#) but annoyingly close.

For that matter I would have preferred numbering the other way, starting at the bottom going up, like de Bruijn indices. That way the numbering would be local and wouldn't depend on where the circular subtree occurs. Technically that would be an easy change, and if we agree that the numbers are unreliable right now, we might as well.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Sat, 14 May 2022 13:46:02 GMT) Full text and rfc822 format available.

Message #23 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 55395 <at> debbugs.gnu.org, Lars Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Sat, 14 May 2022 09:45:15 -0400
>> The main goal is to avoid inf-looping and the #NNN chosen is
>> somewhat arbitrary.
> It seems to have sort-of worked before and was broken, inadvertently and
> with the best intentions, by a later change.
>
> Additionally the #N value appears to be correct for other object types. For example,
>
>   [a [b #1=[[c #1# d]]]]
>
> is printed as
>
>   [a [b [[c #2 d]]]]
>
> which is consistent with the manual.

I do have the impression that it used to be "correct", but I can't
remember of a single time where I actually made use of that NNN.

And even if you know what it means and it works correctly, it's pretty
hard for a normal human to correctly count the depth starting from
the root.

I suspect if we want to "do better", printing "the beginning" of the
object to which we're looping (and saying explicitly that there's
a cycle) will be a lot more useful to the average user.
[ Or we could even print "the period" rather than "the beginning".  ]

>> I'm personally more bothered by the fact that those #NNN use exactly the
>> same syntax as used with `print-circle` yet they don't have the
>> same semantics.
> The syntax isn't exactly the same (#N vs #N= and #N#) but annoyingly close.

Indeed, it's not as bad as I remembered.

> For that matter I would have preferred numbering the other way, starting at
> the bottom going up, like de Bruijn indices.

I love&hate de Bruijn indices as much as the next guy, but they're not
human-friendly (even more than the "like de Bruijn levels" we currently
use).


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Wed, 18 May 2022 14:31:02 GMT) Full text and rfc822 format available.

Message #26 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 55395 <at> debbugs.gnu.org, Lars Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Wed, 18 May 2022 16:29:51 +0200
[Message part 1 (text/plain, inline)]
14 maj 2022 kl. 15.45 skrev Stefan Monnier <monnier <at> iro.umontreal.ca>:

> I do have the impression that it used to be "correct", but I can't
> remember of a single time where I actually made use of that NNN.
> 
> And even if you know what it means and it works correctly, it's pretty
> hard for a normal human to correctly count the depth starting from
> the root.

It is. Counting upwards from a leaf seems slightly easier.

Perhaps these attempts to generate a meaningful circularity reference is a fool's errand and we should just go with #!circle! or something similar.

Anyway, I'm attaching a patch that tries to put some meaning back in the ` . #N` notation: it's an index into the same list, as it used to be, I think, prior to the switch from Floyd to Brent. This is done by keeping track of the index of the tortoise at all times, which isn't very expensive at all.

Without the patch: (rho 4 1) => (1 2 3 4 5 5 5 . #3)
With the patch:    (rho 4 1) => (1 2 3 4 5 5 5 . #6)

which should be a mild improvement.
It's still ambiguous:

 (1 1 . #1)

could mean either

 #1=(1 . #1#)

or

 #1=(1 1 . #1#)

and

 [(1 2 3 . #0)]

could mean either

 [#1=(1 2 3 . #1#)]

or
 #1=[(1 2 3 . #1#)]

but maybe it's less wrong, with room for future improvement?

[circular-list-print-index.diff (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Wed, 18 May 2022 21:17:02 GMT) Full text and rfc822 format available.

Message #29 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 55395 <at> debbugs.gnu.org, Lars Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Wed, 18 May 2022 17:16:16 -0400
>  [(1 2 3 . #0)]
>
> could mean either
>
>  [#1=(1 2 3 . #1#)]
>
> or
>
>  #1=[(1 2 3 . #1#)]

AFAIK it *should* mean the latter (#0 is the root of the overall
printed object, not just the list).

Mattias Engdegård [2022-05-18 16:29:51] wrote:

> Perhaps these attempts to generate a meaningful circularity reference is
> a fool's errand and we should just go with #!circle! or something similar.

Yup.  But we don't shy away from playing the fools.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#55395; Package emacs. (Mon, 23 May 2022 15:01:02 GMT) Full text and rfc822 format available.

Message #32 received at 55395 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 55395 <at> debbugs.gnu.org, Lars Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#55395: What does (1 2 3 . #2) mean?
Date: Mon, 23 May 2022 16:59:57 +0200
18 maj 2022 kl. 23.16 skrev Stefan Monnier <monnier <at> iro.umontreal.ca>:
> 
>> [(1 2 3 . #0)]
>> 
>> could mean either
>> 
>> [#1=(1 2 3 . #1#)]
>> 
>> or
>> 
>> #1=[(1 2 3 . #1#)]
> 
> AFAIK it *should* mean the latter (#0 is the root of the overall
> printed object, not just the list).

Yes, but the code was already a bit ambiguous in that respect. We don't keep track of the cons-level depth when printing; print_depth treats each list nesting as one step regardless of where in the list the nesting occurs. I suppose this could be remedied but I'm not going to work on it right now.

The previously attached patch has been pushed to master, on the grounds that it should be strictly better than what we had before; correctness should be back at the level before the change in circularity detection algorithm broke the tail index completely.

> Yup.  But we don't shy away from playing the fools.

You know me, I don't even need to play one. It all comes natural.





This bug report was last modified 3 years and 24 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.