From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: MON KEY Newsgroups: gmane.emacs.devel Subject: `setplist' on local var escaping let binding Date: Wed, 20 Oct 2010 19:28:17 -0400 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: dough.gmane.org 1287617310 26414 80.91.229.12 (20 Oct 2010 23:28:30 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 20 Oct 2010 23:28:30 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Oct 21 01:28:29 2010 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1P8i55-0002Ff-Qh for ged-emacs-devel@m.gmane.org; Thu, 21 Oct 2010 01:28:28 +0200 Original-Received: from localhost ([127.0.0.1]:53321 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8i54-0007ii-US for ged-emacs-devel@m.gmane.org; Wed, 20 Oct 2010 19:28:26 -0400 Original-Received: from [140.186.70.92] (port=50040 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8i4z-0007iQ-45 for emacs-devel@gnu.org; Wed, 20 Oct 2010 19:28:22 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P8i4x-0004ZY-UC for emacs-devel@gnu.org; Wed, 20 Oct 2010 19:28:21 -0400 Original-Received: from mail-wy0-f169.google.com ([74.125.82.169]:43695) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P8i4x-0004ZS-L1 for emacs-devel@gnu.org; Wed, 20 Oct 2010 19:28:19 -0400 Original-Received: by wyf28 with SMTP id 28so4570438wyf.0 for ; Wed, 20 Oct 2010 16:28:17 -0700 (PDT) Original-Received: by 10.216.239.200 with SMTP id c50mr8885437wer.63.1287617297407; Wed, 20 Oct 2010 16:28:17 -0700 (PDT) Original-Received: by 10.216.67.195 with HTTP; Wed, 20 Oct 2010 16:28:17 -0700 (PDT) X-Google-Sender-Auth: kHdciKhd8AHFuZDSbS0gHDIFnrM X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:131916 Archived-At: I noticed today that if I `setplist' on a null let bound local var inside a call to `with-current-buffer' the symbol's property list can escape the scope of the let binding. This happens in one case but not in another. I can't figure out why. Does elisp treat a symbol's plist as a global resource distinct from its value cell? The Common Lisp ANSI spec has this to say w/re `symbol-plist': ,---- | The use of `setf' should be avoided, since a symbol's property list | is a global resource that can contain information established and | depended upon by unrelated programs in the same Lisp image. `---- I reviewed the Emacs Lisp specification :P for a similarly equivalent cautionary missive but I still can't tell if this is a bug or not. So, I'm asking here. Following is an attempt at illustrating what is happening: (progn (unintern "local-var" obarray) (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var)))) ;=> (prop1 1 prop2 2 prop3 3) > (symbol-plist 'local-var) ;=> nil Now unintern the `local-var' symbol: (unintern "local-var" obarray) ;=> t Following expression also puts properties on `local-var', but this time its properties "escape" the let-binding: (progn (ignore) (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var)))) ;=> (prop1 1 prop2 2 prop3 3) (symbol-plist 'local-var) ;=> (prop1 1 prop2 2 prop3 3) This seems either wrong or inconsisistent because `local-var' was well... local. I would expect the symbol-plist to also return nil outside the let binding as it did in the first example. I thought maybe the issue was around `with-temp-buffer' so I tried this: (with-current-buffer (get-buffer-create "*fresh-buffer-for-local-var*") (progn (unintern "local-var" obarray) (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var))))) ;=> (prop1 1 prop2 2 prop3 3) (symbol-plist 'local-var) ;=> nil To mimic `with-temp-buffer' macro rid the "temp-buffer" w/: (kill-buffer (get-buffer-create "*fresh-buffer-for-local-var*")) Also, to meake sure that `local-var' is really dead: (unintern "local-var" obarray) Trying the same, but without uninterning `local-var' inside `progn': (with-current-buffer (get-buffer-create "*fresh-buffer-for-local-var*") (progn (ignore) (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var))))) ;=> (prop1 1 prop2 2 prop3 3) (symbol-plist 'local-var) ;=> (prop1 1 prop2 2 prop3 3) Now without the `progn' wrapper but keeping the `unintern': (with-current-buffer (get-buffer-create "*fresh-buffer-for-local-var*") (unintern "local-var" obarray) (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var)))) ;=> (prop1 1 prop2 2 prop3 3) (symbol-plist 'local-var) ;=> nil Again, just to be sure, rid any possibility that `local-var' is lingering in some unseen Emacs crevice: (kill-buffer (get-buffer-create "*fresh-buffer-for-local-var*")) (unintern "local-var" obarray) Now, without the `progn' wrapper and without the `unintern': (with-current-buffer (get-buffer-create "*fresh-buffer-for-local-var*") (let (local-var) (with-temp-buffer (setplist 'local-var '(prop1 1 prop2 2 prop3 3)) (symbol-plist 'local-var)))) ;=> (prop1 1 prop2 2 prop3 3) (symbol-plist 'local-var) ;=> (prop1 1 prop2 2 prop3 3) I've verified the above behavior w/ emacs -Q (emacs-version) ;=> "GNU Emacs 23.2.1 (i686-pc-linux-gnu, GTK+ Version 2.20.0) ; of 2010-05-10" It seems fair to assume that neither the special form `progn' nor the macro `with-temp-buffer' are causing the divergent behavior. So, what gives? Is there something happening around forms containing `unintern'/`let' which allow a null symbols's plist to return to nil whereas it otherwise won't? And, more specifically what is the correct behavior? Is it expected that every interned symbol's plist should have global extent independent of its scope? I ask because I'm interested to learn how this may affect the proposed integration of the lexbind? If what I have pointed out above is some sort of bug (abstract though it may be) my suspicion is that the "problem" originates with the priveleged space Emacs' extends to buffers. No doubt this extension has been reasonable where the buffer is a primary data-structure for Emacs the _text editor_. However, if there is to be a lexbind, does this not imply a certain acknowledgement that Emacs is also a _programming language_? There is a tension here around buffer/text-editor vs. expressions/lisp Indeed, I've been informed by at least one emacs-devel that, "Emacs is a _text editor_ not a programming language" Is it not unreasonable to assume that some aspects of the buffers priveleged status _must_ move over to make room for the lexbind? IOW will any more "space" be affored Emacs lisp-lists or will the buffer continue on as the primary "owner" of variable extent/scope? -- /s_P\