From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: Circular records: how do I best handle them? (The new correct warning position branch now bootstraps in native compilation!) Date: Fri, 31 Dec 2021 21:53:22 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11224"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Dec 31 22:54:25 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n3Pqz-0002k4-2x for ged-emacs-devel@m.gmane-mx.org; Fri, 31 Dec 2021 22:54:25 +0100 Original-Received: from localhost ([::1]:41558 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n3Pqx-0001Ti-VA for ged-emacs-devel@m.gmane-mx.org; Fri, 31 Dec 2021 16:54:23 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:43506) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n3PqI-0000od-MX for emacs-devel@gnu.org; Fri, 31 Dec 2021 16:53:42 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:31174 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.90_1) (envelope-from ) id 1n3PqG-0006Mo-9s for emacs-devel@gnu.org; Fri, 31 Dec 2021 16:53:42 -0500 Original-Received: (qmail 92095 invoked by uid 3782); 31 Dec 2021 21:53:23 -0000 Original-Received: from acm.muc.de (p4fe1597e.dip0.t-ipconnect.de [79.225.89.126]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 31 Dec 2021 22:53:23 +0100 Original-Received: (qmail 1249 invoked by uid 1000); 31 Dec 2021 21:53:22 -0000 Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de Received-SPF: pass client-ip=193.149.48.1; envelope-from=acm@muc.de; helo=mail.muc.de X-Spam_score_int: 1 X-Spam_score: 0.1 X-Spam_bar: / X-Spam_report: (0.1 / 5.0 requ) PLING_QUERY=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:283770 Archived-At: Hello, Stefan. On Thu, Dec 30, 2021 at 13:37:47 -0500, Stefan Monnier wrote: > >> >> Hmm... circularity is quite normal in data structures, yes. > >> >> But presumably this is only applied to source code where circularity is > >> >> very rare. Could it be that you end up recursing in elements which > >> >> actually aren't part of the source code (and hence can't have > >> >> symbols-with-positions)? > >> > I honestly don't know at the moment. > >> I think it's worth the effort to try and track this down. Maybe we can > >> completely circumvent the problem. > > I don't think there are any such cases. > Hmm... I thought this whole circular records thread started because you > bumped into such a case. I feel like I'm misunderstanding something. What I bumped into was circularly linked vectors in the source code being compiled. I've amended the reader so that it doesn't put positions on symbols which are read as components of other structures such as byte compiled functions, text property lists in strings, and so on. (Actually, there was very little to amend.). I've amended macroexp-strip-symbol-positions so that it ignores circularity unless it hits an infinite recursion, in which case it starts again, recording all components found in hash tables. I committed these changes a short time ago. > >> So the symposes can end up in 2 places: > >> - in the .elc file: no need to strip the pos here, just make sure the > >> symbols get printed without their position. > > The positions get stripped before the code is dumped to the .elc. > Why bother? You can just have a `print-symbols-without-position` which > you let-bind around the printing code. I think I've got that already, though it's a long time since I looked at it. > >> - elsewhere: that's the problematic part because this only occurs where > >> the source code gets stealthy passed elsewhere, e.g. when a macro > >> calls (put ARG1 'foo ARG2) during the macro expansion (rather than > >> returning that chunk of code in the expansion). > > This isn't a problem. If it is a compiled macro doing this, the > > positions will already be gone from the symbols. If it is from an > > uncompiled macro, XSYMBOL in Feval's subroutines does the Right Thing. > I didn't mean sympos coming from the macro but sympos coming from the > args passed to the macro. Something like: > (defmacro foobar-really (arg1 arg2) > (puthash arg1 arg2 foobar-remember) > `(progn (do-something ,arg1) (do-something-else ,arg2))) Args which are symbols with positions are first and foremost symbols. They behave like symbols when used. The test of this is that Emacs bootstraps, despite having many macro expressions like ,@body which expand to expressions with positions. > The `remember` property will end up containing symbols-with-pos if > `arg2` contains symbols. In that (puthash arg1 arg2 foobar-remember), if the key is a symbol with position, it is stripped. I think the value will keep its positions. This might still be a problem. > > It's used all over the place. In eval-when/and-compile, it is used > > before the evaluation. It is used before dumping the byte compiled code > > to the file.elc, and before passing this code to the native compiler. > > Several (?most) of the byte-compile-file-form-... functions use it. > > It's used in the newish keymap functions near the end of bytecomp.el, in > > byte-compile-annotate-call-tree, etc. Also in cl-define-compiler-macro, > > and internal-macro-expand-for-load. > Interesting. Why do you need it at so many places? > What is it usually used for? Stipping positions from compiled code before dumping it to an .elc file, and also before passing the compiled code to the native compiler. The fact is these positions on the symbols are unwanted for most uses of symbols around compilation, being needed only in the analysis phase of the source code. > > Additionally, also from Fput, to prevent symbols with positions > > getting into symbol property lists. > IIUC this is for the kind of example I showed above (tho I used > `puthash` instead of `put`)? > > Yes, I have to do this. I am still debating whether just to do it > > (which might slow things down quite a bit), or to do it in a > > condition-case handler after the recursion has exceeded the 1,600 > > max-lisp-eval-depth. I'm inclined towards the latter at the moment. > Using a (weak) hash-table may actually speed things up if you call it > from lots and lots of places and it thus ends up being applied several > times (redundantly) to the same data. In the end I went with the condition-case approach, based on a gut feeling that hash tables aren't very fast, and they're needed only rarely, certainly whilst bootstrapping Emacs. > > For other Lisp objects with a read syntax, such as char tables and > > decorated strings, I intend to amend the reader just to output plain > > symbols for them. > Sounds reasonable. I've done this now. Feel free to look at the new version of scratch/correct-warning-pos. And a Happy New Year! > Stefan -- Alan Mackenzie (Nuremberg, Germany).