unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Allow value of PRINT_CIRCLE to be modified from Elisp?
@ 2012-04-19 13:09 Toby Cubitt
  2012-04-19 22:12 ` Stefan Monnier
  0 siblings, 1 reply; 13+ messages in thread
From: Toby Cubitt @ 2012-04-19 13:09 UTC (permalink / raw)
  To: emacs-devel

print.c defines an arbitrary fixed limit

  #define PRINT_CIRCLE 200

on the depth to which a lisp object can be printed, before it bails out
with the "Apparently circular structure being printed" error.

Apparently, no one anticipated wanting to print highly nested Elisp
structures. But this arbitrary limit is breaking some of the
functionality in Elisp packages I maintain (see below for a detailed
explanation).

Could the #define PRINT_CIRCLE constant be turned into a DEFVAR_INT
`max-lisp-print-depth' variable, so that it could be adjusted from Elisp
when more print depth is needed?


The motivation for this request is that I've been playing around with
implementing persistent storage of undo history in undo-tree.el. This is
trivial to implement these days thanks to recent Emacs' ability to `read'
back the output of non-nil print-circle `prin1' output.

Unfortunately, undo history typically grows very long, even in a
moderately heavily edited buffer, creating very deep undo-trees. For all
but the most trivial test buffers, saving undo-tree history to file using
prin1 hits the arbitrary PRINT_CIRCLE limit and fails.

I've hit exactly the same problem before in my predictive.el package
(actually, in dict-tree.el, which implements the trie-based dictionary
data structures I use there). If one stores long strings in the
dictionaries, persistent storage of the dictionaries (again just
implemented using the natural prin1 method) hits PRINT_CIRCLE and fails.

So I now have two real-world use cases where the PRINT_CIRCLE limit is
causing problems.

I know I could work-around the problem using a more complicated
persistent storage implementation than prin1. But this would effectively
mean writing my own data-structure-specific re-implementations of prin1.
And that just seems wrong when we have all the beauty of Lisp read/print
syntax to hand.


Because the depth of the dictionary trees is proportional to the longest
string they store, which is typically upper-bounded by some not-too-big
constant, it's quite rare to hit this issue at all in predictive.el. And
the simple solution of increasing the value of PRINT_CIRCLE in print.c
and recompiling avoids the problem in any real-world use. (Though the
average Emacs user probably wouldn't call this solution "simple"!)

But the depth of an undo-tree is proportional to the length of the undo
history. PRINT_CIRCLE would have to be very large to avoid the problem in
undo-tree.el, probably too big to usefully protect against infinite
recursion elsewhere. An Elisp-configurable limit would seem the better
way to go, so that it can temporarily be let-bound to a larger value when
printing the undo-trees.

eval.c has adjustable `max-lisp-eval-depth', with big scary warnings in
the docstring about potential stack overflows if it's increased too
much. Could we add a `max-lisp-print-depth', with similar warnings?


I looked into writing a patch for this myself, but print.c defines
being_printed as a global static array for use in print_preprocess and
print_object:

  static Lisp_Object being_printed[PRINT_CIRCLE];

This would have to be turned into a dynamically allocated array
(allocated in the print c function?), and I'm not familiar enough with
Emacs' c code memory management to know how to implement this correctly.

Toby
-- 
Dr T. S. Cubitt
Mathematics and Quantum Information group
Department of Mathematics
Complutense University
Madrid, Spain

email: tsc25@cantab.net
web:   www.dr-qubit.org



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2012-10-02 15:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-19 13:09 Allow value of PRINT_CIRCLE to be modified from Elisp? Toby Cubitt
2012-04-19 22:12 ` Stefan Monnier
2012-04-19 22:25   ` Toby Cubitt
2012-04-20 13:03     ` Stefan Monnier
2012-04-21 11:44       ` Toby Cubitt
2012-10-02 10:19         ` Toby Cubitt
2012-10-02 13:23           ` Stefan Monnier
2012-10-02 14:04             ` Toby Cubitt
2012-10-02 14:07               ` Donald Ephraim Curtis
2012-10-02 15:00                 ` Stefan Monnier
2012-04-20  7:23   ` Andreas Schwab
2012-04-20 11:36     ` Stefan Monnier
2012-04-20 12:06       ` Andreas Schwab

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).