From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Toby Cubitt Newsgroups: gmane.emacs.devel Subject: Allow value of PRINT_CIRCLE to be modified from Elisp? Date: Thu, 19 Apr 2012 15:09:13 +0200 Message-ID: <20120419130912.GA12961@c3po.home> Reply-To: Toby Cubitt NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1334841006 16517 80.91.229.3 (19 Apr 2012 13:10:06 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 19 Apr 2012 13:10:06 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Apr 19 15:10:02 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1SKr7X-0008Eh-SJ for ged-emacs-devel@m.gmane.org; Thu, 19 Apr 2012 15:10:00 +0200 Original-Received: from localhost ([::1]:58261 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SKr7W-0005GD-QM for ged-emacs-devel@m.gmane.org; Thu, 19 Apr 2012 09:09:58 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:41355) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SKr7Q-0005Fv-Qs for emacs-devel@gnu.org; Thu, 19 Apr 2012 09:09:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SKr7K-00072Z-3V for emacs-devel@gnu.org; Thu, 19 Apr 2012 09:09:52 -0400 Original-Received: from starfish.geekisp.com ([216.168.135.166]:1076) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SKr7J-000702-Uf for emacs-devel@gnu.org; Thu, 19 Apr 2012 09:09:46 -0400 Original-Received: (qmail 4160 invoked by uid 1003); 19 Apr 2012 13:09:41 -0000 Original-Received: from localhost (localhost.geekisp.com [127.0.0.1]) by localhost.geekisp.com (tmda-ofmipd) with ESMTP; Thu, 19 Apr 2012 09:09:39 -0400 Content-Disposition: inline X-PGP-Key: http://www.dr-qubit.org/gpg-toby.asc User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.11 (Ladyburn) X-Primary-Address: toby@dr-qubit.org X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 216.168.135.166 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:149815 Archived-At: 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